对于2d numpy数组的每一行,在第二个2d数组中获取相等行的索引

时间:2018-04-22 10:08:46

标签: python arrays numpy

我有两个巨大的2d numpy整数数组X和U,其中U被假定只有unqiue行。对于X中的每一行,我想获得U中匹配行的相应行索引(如果有的话,则为-1)。例如,如果以下数组作为输入传递:

U = array([[1, 4],
       [2, 5],
       [3, 6]])

X = array([[1, 4],
       [3, 6],
       [7, 8],
       [1, 4]])

输出应为:

array([0,2,-1,0])

使用Numpy有没有一种有效的方法(或类似的东西)?

@Divakar: 你的方法对我失败了

print(type(rows), rows.dtype, rows.shape)
print(rows[:10])
print(search2D_indices(rows[:10], rows[:10]))

<class 'numpy.ndarray'> int32 (47398019, 5)
[[65536     1     1     1    17]
 [65536     1     1     1   153]
 [65536     1     1     2   137]
 [65536     1     1     3   153]
 [65536     1     1     9   124]
 [65536     1     1    13   377]
 [65536     1     1    13   134]
 [65536     1     1    13   137]
 [65536     1     1    13   153]
 [65536     1     1    13   439]]
[ 0  1  2  3  4 -1 -1 -1 -1  9]

3 个答案:

答案 0 :(得分:3)

方法#1

灵感来自this solutionFind the row indexes of several values in a numpy array ,这是使用searchsorted的矢量化解决方案 -

In [121]: U
Out[121]: 
array([[1, 4],
       [2, 5],
       [3, 6]])

In [122]: X
Out[122]: 
array([[1, 4],
       [3, 6],
       [7, 8],
       [1, 4]])

In [123]: search2D_indices(U, X, fillval=-1)
Out[123]: array([ 0,  2, -1,  0])

示例运行 -

dims

方法#2

延伸到具有负整数的案例,我们需要相应地偏移1D和转换为def search2D_indices_v2(X, searched_values, fillval=-1): X_lim = X.max()-X.min(0) searched_values_lim = searched_values.max()-searched_values.min(0) dims = np.maximum(X_lim, searched_values_lim)+1 s = dims.cumprod() X1D = X.dot(s) searched_valuesID = searched_values.dot(s) sidx = X1D.argsort() idx = np.searchsorted(X1D,searched_valuesID,sorter=sidx) idx[idx==len(sidx)] = 0 idx_out = sidx[idx] return np.where(X1D[idx_out] == searched_valuesID, idx_out, fillval) ,如此 -

In [142]: U
Out[142]: 
array([[-1, -4],
       [ 2,  5],
       [ 3,  6]])

In [143]: X
Out[143]: 
array([[-1, -4],
       [ 3,  6],
       [ 7,  8],
       [-1, -4]])

In [144]: search2D_indices_v2(U, X, fillval=-1)
Out[144]: array([ 0,  2, -1,  0])

示例运行 -

views

方法#3

另一个基于# https://stackoverflow.com/a/45313353/ @Divakar def view1D(a, b): # a, b are arrays a = np.ascontiguousarray(a) b = np.ascontiguousarray(b) void_dt = np.dtype((np.void, a.dtype.itemsize * a.shape[1])) return a.view(void_dt).ravel(), b.view(void_dt).ravel() def search2D_indices_views(X, searched_values, fillval=-1): X1D,searched_valuesID = view1D(X, searched_values) sidx = X1D.argsort() idx = np.searchsorted(X1D,searched_valuesID,sorter=sidx) idx[idx==len(sidx)] = 0 idx_out = sidx[idx] return np.where(X1D[idx_out] == searched_valuesID, idx_out, fillval) -

<li class="CLASSNAME">
      <div class="DIV1">
        <div class="DIV2">
          <div class="DIV3">
            <div class="DIV4">
            <a class="HYPERLINK_CLASSNAME" title="TITLE"> ... </a>
            </div>
          </div>
        </div>
      </div> 
    </li> 

<li class="CLASSNAME">
      <div class="DIV1">
        <div class="DIV2">
          <div class="DIV3">
            <div class="DIV4">
            <a class="HYPERLINK_CLASSNAME" title="TITLE2"> ... </a>
            </div>
          </div>
        </div>
      </div> 
    </li> 

答案 1 :(得分:0)

这是一个基于字典的方法:

import numpy as np

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

X = np.array([[1, 4],
              [3, 6],
              [7, 8],
              [1, 1]])

d = {v: k for k, v in enumerate(map(tuple, U))}

res = np.array([d.get(tuple(a), -1) for a in X])

# [ 0  2 -1 -1]

答案 2 :(得分:0)

您可以使用广播以便以矢量化方式确定项目的权益。之后您可以简单地使用all功能 通过适当的轴来获得所需的真值对应于预期的指数。最后,使用np.where获取权益的指数 发生并简单地将其重新分配给先前创建的填充-1的数组。

In [47]: result = np.full(X.shape[0], -1)

In [48]: x, y = np.where((X[:,None] == U).all(-1))

In [49]: result[x] = y

In [50]: result
Out[50]: array([ 0,  2, -1,  0])

请注意,正如在文档中也提到的那样,请注意广泛投射:

  

虽然这在代码行方面非常有效,但它可能具有计算效率,也可能不具备计算效率。问题是在算法的中间步骤中计算的三维diff阵列。对于小型数据集,在阵列上创建和操作可能非常快。但是,大型数据集将生成一个计算效率低的大型中间阵列。