我有一个数组X:
X = np.array([[4, 2],
[9, 3],
[8, 5],
[3, 3],
[5, 6]])
并且我希望找到该数组中几个值所在行的索引:
searched_values = np.array([[4, 2],
[3, 3],
[5, 6]])
在本例中,我希望得到如下结果:
[0,3,4]
我有一个代码来做这件事,但我认为它太复杂了:
X = np.array([[4, 2],
[9, 3],
[8, 5],
[3, 3],
[5, 6]])
searched_values = np.array([[4, 2],
[3, 3],
[5, 6]])
result = []
for s in searched_values:
idx = np.argwhere([np.all((X-s)==0, axis=1)])[0][1]
result.append(idx)
print(result)
我发现this answer解决了类似的问题,但它只适用于一维阵列。
有没有办法用更简单的方式做我想做的事?
8条答案
按热度按时间ghhaqwfi1#
方法1
一种方法是使用
NumPy broadcasting
,如下所示方法2
一种内存效率高的方法是将每行转换为线性索引等效项,然后使用
np.in1d
,如下所示-方法#3
另一种使用
np.searchsorted
并具有相同的转换为线性索引等效项的高效内存方法将如下所示-请注意,此
np.searchsorted
方法假设X
中的searched_values
中的每一行都有匹配。np.ravel_multi_index
如何工作?此函数给出了线性指数等效数。它接受由
n-dimensional indices
组成的2D
数组,该数组被设置为列和n维网格本身的形状,这些索引将被Map到该n维网格上,并计算等价的线性索引。让我们使用手头问题的输入。以输入
X
为例,注意它的第一行。由于我们正在尝试将X
的每一行转换为它的线性索引等效项,并且由于np.ravel_multi_index
假设每一列都是一个索引元组,因此在提供给该函数之前,我们需要转置X
。因为在本例中,X
中每行的元素数是2
,所以要Map到的n维网格将是2D
。如果X
中每行有3个元素,则将使用3D
网格进行Map等。要了解此函数如何计算线性指数,请考虑
X
的第一行-我们有n维网格的形状为
dims
-让我们创建2维网格,看看Map是如何工作的,并使用
np.ravel_multi_index
计算线性指数-让我们设置来自
X
的第一个索引元组,即从X
到网格的第一行-现在,要查看刚刚设置的元素的线性索引,让我们展平并使用
np.where
来检测1
。如果考虑到行主排序,也可以计算出这一点。
让我们使用
np.ravel_multi_index
并验证这些线性指数-因此,我们将拥有与来自
X
的每个索引元组对应的线性索引,即来自X
的每一行。选择
np.ravel_multi_index
的维度,形成唯一的线性指数现在,将
X
的每一行视为n维网格的索引元组并将每个这样的元组转换为标量背后的想法是具有对应于唯一元组的唯一标量,即X
中的唯一行。让我们再来看看
X
-现在,正如上一节所讨论的,我们将每一行视为索引元组。在每个这样的索引元组中,第一个元素将表示n维网格的第一个轴,第二个元素将是该网格的第二个轴,依此类推,直到
X
中每行的最后一个元素。本质上,每一列代表网格的一个维度或轴。如果我们要将X
中的所有元素Map到相同的n维网格上,我们需要考虑这种建议的n维网格的每个轴的最大拉伸。假设我们处理的是X
中的正数,这样的伸长量将是X
+1中每列的最大值。因此,例如,X[1,0] == 9
将Map到建议栅格的第10行。同样,X[4,1] == 6
将转到该网格的7th
列。所以,在我们的样例中,我们有-
因此,对于我们的样例,我们至少需要一个形状为
(10,7)
的网格。维度上更多的长度不会有什么坏处,还会给我们提供唯一的线性指数。结束语:这里需要注意的一件重要事情是,如果我们在
X
中有负数,我们需要沿着X
中的每一列添加适当的偏移量,以便在使用np.ravel_multi_index
之前使这些索引元组成为正数。fcwjkofz2#
另一种选择是使用
asvoid
(下面)到view
每行作为void
dtype的单个值。这会将二维数组减少为一维数组,从而允许您照常使用np.in1d
:guz6ccqo3#
numpy_indexed包(免责声明:我是它的作者)包含了有效执行此类操作的功能(还在幕后使用了搜索排序)。就功能而言,它相当于向量化的list.index:
请注意,使用‘丢失’kwarg,您可以完全控制丢失物品的行为,它也适用于nd数组(fi;图像堆栈)。
更新:使用与@Rik
X=[520000,28,28]
和searched_values=[20000,28,28]
相同的形状,它在0.8064 secs
中运行,使用Missing=-1来检测和表示X中不存在的条目。w46czmvw4#
这里有一个非常快速的解决方案,使用NumPy和hashlib可以很好地进行扩展。它可以在几秒钟内处理大尺寸矩阵或图像。我在520000 X(28 X 28)阵列和20000 X(28 X 28)阵列上使用它,在我的中央处理器上只用了2秒
代码:
产出:
ru9i0ody5#
或
如果您想要一个平面列表(假设每个搜索值正好有一个匹配)。
kq0g1dla6#
另一种方法是使用
scipy.spatial.distance
中的cdist
函数,如下所示:基本上,我们得到
X
的行号,这些行号到searched_values
的行距为零,这意味着它们是相等的。如果您将行视为坐标,这是有意义的。kuarbcqp7#
我有类似的要求,下面的内容对我很管用:
wqnecbli8#
以下是我的想法:
测试:
输出: