我有两个巨大的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]
答案 0 :(得分:3)
方法#1
灵感来自this solution
到Find 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阵列。对于小型数据集,在阵列上创建和操作可能非常快。但是,大型数据集将生成一个计算效率低的大型中间阵列。