Python 查找numpy数组中多个值的行索引

Python 查找numpy数组中多个值的行索引,python,arrays,numpy,Python,Arrays,Numpy,我有一个数组X: X = np.array([[4, 2], [9, 3], [8, 5], [3, 3], [5, 6]]) 我希望找到这个数组中多个值行的索引: searched_values = np.array([[4, 2], [3, 3], [5, 6

我有一个数组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)
我发现了一个类似的问题,但它只适用于一维数组

有没有一种更简单的方法来做我想做的事情?

方法#1

一种方法是像这样使用-

np.where((X==searched_values[:,None]).all(-1))[1]
dims = X.max(0)+1
out = np.where(np.in1d(np.ravel_multi_index(X.T,dims),\
                    np.ravel_multi_index(searched_values.T,dims)))[0]
dims = X.max(0)+1
X1D = np.ravel_multi_index(X.T,dims)
searched_valuesID = np.ravel_multi_index(searched_values.T,dims)
sidx = X1D.argsort()
out = sidx[np.searchsorted(X1D,searched_valuesID,sorter=sidx)]
方法#2

一种节省内存的方法是将每一行转换为等价的线性索引,然后像这样使用-

np.where((X==searched_values[:,None]).all(-1))[1]
dims = X.max(0)+1
out = np.where(np.in1d(np.ravel_multi_index(X.T,dims),\
                    np.ravel_multi_index(searched_values.T,dims)))[0]
dims = X.max(0)+1
X1D = np.ravel_multi_index(X.T,dims)
searched_valuesID = np.ravel_multi_index(searched_values.T,dims)
sidx = X1D.argsort()
out = sidx[np.searchsorted(X1D,searched_valuesID,sorter=sidx)]
方法#3

另一种高效内存的方法是使用相同的转换为线性索引等价物的原理-

np.where((X==searched_values[:,None]).all(-1))[1]
dims = X.max(0)+1
out = np.where(np.in1d(np.ravel_multi_index(X.T,dims),\
                    np.ravel_multi_index(searched_values.T,dims)))[0]
dims = X.max(0)+1
X1D = np.ravel_multi_index(X.T,dims)
searched_valuesID = np.ravel_multi_index(searched_values.T,dims)
sidx = X1D.argsort()
out = sidx[np.searchsorted(X1D,searched_valuesID,sorter=sidx)]
请注意,此
np.searchsorted
方法假定
X
中的
searched\u值中的每一行都有匹配项


它是如何工作的? 此函数为我们提供了线性索引等价数。它接受一个
2D
数组,设置为列和n维网格本身的形状,这些索引将映射到该网格上,并计算等效的线性索引

让我们利用手头问题的输入。以输入
X
为例,记下它的第一行。因为,我们试图将
X
的每一行转换为它的线性索引等价物,并且因为
np.ravel\u multi\u index
假设每一列都是一个索引元组,所以在输入函数之前,我们需要对
X
进行转置。由于在这种情况下,
X
中每行元素的数量是
2
,因此要映射到的n维网格将是
2D
。在
X
中,每行有3个元素,它应该是
3D
网格,用于映射等等

查看此函数如何计算线性索引,考虑<代码> x < /代码> -< /p>的第一行。

In [77]: X
Out[77]: 
array([[4, 2],
       [9, 3],
       [8, 5],
       [3, 3],
       [5, 6]])
In [77]: X
Out[77]: 
array([[4, 2],
       [9, 3],
       [8, 5],
       [3, 3],
       [5, 6]])
我们将n维网格的形状设置为
dims
-

In [78]: dims
Out[78]: array([10,  7])
让我们创建二维网格,看看映射是如何工作的,并使用
np.ravel\u multi\u index
-

In [79]: out = np.zeros(dims,dtype=int)

In [80]: out
Out[80]: 
array([[0, 0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 0]])
让我们设置
X
中的第一个索引元组,即
X
中的第一行-

In [81]: out[4,2] = 1

In [82]: out
Out[82]: 
array([[0, 0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 0],
       [0, 0, 1, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 0]])
现在,为了查看刚刚设置的元素的线性索引等价物,让我们展平并使用
np.where
来检测
1

In [83]: np.where(out.ravel())[0]
Out[83]: array([30])
如果考虑到行主顺序,也可以计算此值

让我们使用
np.ravel\u multi\u index
并验证这些线性索引-

In [84]: np.ravel_multi_index(X.T,dims)
Out[84]: array([30, 66, 61, 24, 41])
因此,我们将具有与
X
中的每个索引元组对应的线性索引,即
X
中的每一行

np.ravel\u多重索引选择维度
以形成唯一的线性索引

现在,将
X
的每一行视为一个n维网格的索引元组,并将每一个这样的元组转换为一个标量,其背后的思想是具有对应于唯一元组的唯一标量,即
X
中的唯一行

让我们再看一看
X
-

In [77]: X
Out[77]: 
array([[4, 2],
       [9, 3],
       [8, 5],
       [3, 3],
       [5, 6]])
In [77]: X
Out[77]: 
array([[4, 2],
       [9, 3],
       [8, 5],
       [3, 3],
       [5, 6]])
现在,如前一节所讨论的,我们将每一行视为索引元组。在每个这样的索引元组中,第一个元素表示n-dim网格的第一个轴,第二个元素表示网格的第二个轴,依此类推,直到
X
中每行的最后一个元素。本质上,每一列将代表网格的一个维度或轴。如果我们要把所有的元素从<代码> x>代码>映射到同一个n-朦胧网格上,我们需要考虑这样一个提出的n-朦胧网格的每个轴的最大拉伸。假设我们处理的是
X
中的正数,那么这样的延伸就是
X
+1中每列的最大值。
+1
是因为Python遵循基于
0的
索引。因此,例如
X[1,0]==9
将映射到建议网格的第10行。类似地,
X[4,1]==6将进入该网格的
7列

因此,对于我们的示例案例,我们有-

In [7]: dims = X.max(axis=0) + 1 # Or simply X.max(0) + 1

In [8]: dims
Out[8]: array([10,  7])
因此,对于我们的示例案例,我们需要一个形状至少为
(10,7)
的网格。沿维度增加长度不会有什么坏处,也会给我们带来唯一的线性指数

结束语:这里需要注意的一件重要事情是,如果我们在
X
中有负数,我们需要在
X
中的每一列添加适当的偏移量,以使这些索引元组成为正数,然后再使用
np.ravel_multi_index

方法1

X = np.array([[4,  2],
              [9,  3],
              [8,  5],
              [3,  3],
              [5,  6]])

S = np.array([[4, 2],
              [3, 3],
              [5, 6]])

result = [[i for i,row in enumerate(X) if (s==row).all()] for s in S]
一种方法是像这样使用-

np.where((X==searched_values[:,None]).all(-1))[1]
dims = X.max(0)+1
out = np.where(np.in1d(np.ravel_multi_index(X.T,dims),\
                    np.ravel_multi_index(searched_values.T,dims)))[0]
dims = X.max(0)+1
X1D = np.ravel_multi_index(X.T,dims)
searched_valuesID = np.ravel_multi_index(searched_values.T,dims)
sidx = X1D.argsort()
out = sidx[np.searchsorted(X1D,searched_valuesID,sorter=sidx)]
方法#2

一种节省内存的方法是将每一行转换为等价的线性索引,然后像这样使用-

np.where((X==searched_values[:,None]).all(-1))[1]
dims = X.max(0)+1
out = np.where(np.in1d(np.ravel_multi_index(X.T,dims),\
                    np.ravel_multi_index(searched_values.T,dims)))[0]
dims = X.max(0)+1
X1D = np.ravel_multi_index(X.T,dims)
searched_valuesID = np.ravel_multi_index(searched_values.T,dims)
sidx = X1D.argsort()
out = sidx[np.searchsorted(X1D,searched_valuesID,sorter=sidx)]
方法#3

另一种高效内存的方法是使用相同的转换为线性索引等价物的原理-

np.where((X==searched_values[:,None]).all(-1))[1]
dims = X.max(0)+1
out = np.where(np.in1d(np.ravel_multi_index(X.T,dims),\
                    np.ravel_multi_index(searched_values.T,dims)))[0]
dims = X.max(0)+1
X1D = np.ravel_multi_index(X.T,dims)
searched_valuesID = np.ravel_multi_index(searched_values.T,dims)
sidx = X1D.argsort()
out = sidx[np.searchsorted(X1D,searched_valuesID,sorter=sidx)]
请注意,此
np.searchsorted
方法假定
X
中的
searched\u值中的每一行都有匹配项


它是如何工作的? 此函数为我们提供了线性索引等价数。它接受一个
2D
数组,设置为列和n维网格本身的形状,这些索引将映射到该网格上,并计算等效的线性索引

让我们利用手头问题的输入。以输入
X
为例,记下它的第一行。因为,我们试图将
X
的每一行转换为它的线性索引等价物,并且因为
np.ravel\u multi\u index
假设每一列都是一个索引元组,所以在输入函数之前,我们需要对
X
进行转置。因为,在这种情况下,
X
中每行的元素数为