查找3d numpy数组中特定行的索引

时间:2015-10-07 18:03:37

标签: python arrays numpy

我正在寻找numpy中的方法来查找3d数组中外部特定行的索引。一个例子是在RBG图像中找到给定颜色集的所有出现,并获取像素坐标。

这个question表明in运算符在数组上表现得很奇怪,而且这个one更接近但是适用于2D数组。

我们假设我们的维度为Z的3d数组(x,y,z)和我们想要匹配的第三维行[s0, s1]

Z = np.zeros((10,20,3), dtype=int)
s0 = np.array([1,2,3])
s1 = np.array([4,5,6])
Z[1,2] = s0
Z[4,5] = s1

我希望所有(x,y) z等于s0s1

到目前为止, argwhere返回s0Z中的一个元素所在的每个匹配项:

> np.argwhere(s0 == Z) 
array([[1, 2, 0],
       [1, 2, 1],
       [1, 2, 2]])

in1d返回一个布尔值为1的数组,其中s0或s1中的元素匹配:

> np.in1d(Z, [s0,s1])

如果我尝试一下这种方式:

> Zravel = np.ascontiguousarray(a).view([('', a.dtype)] * a.shape[-1]).ravel()
> np.all(np.in1d(Zravel, [s0, s1]) == False)

所有元素都是False

有什么想法吗?

1 个答案:

答案 0 :(得分:2)

np.in1d会压缩其输入。因此,您可以提供Zs0s1的堆叠版本,为我们提供一个布尔数组,可以将其重新整形为与Z形状相同的数组。然后,您需要检查匹配索引中的所有TRUE行。实现看起来像这样 -

S = np.row_stack((s0,s1))
out = np.where((np.in1d(Z,S).reshape(Z.shape)).all(2))

你也可以使用broadcasting来解决它 -

out = np.where(((Z == S[:,None,None,:]).all(3)).any(0))

如果您希望将输出堆叠在一个数组中 -

outarr = np.column_stack((out))

要创建S,您可以将np.row_stack替换为np.concatenate,这可能更快,就像这样 -

S = np.concatenate((s0,s1)).reshape(-1,s0.size)

示例运行 -

In [145]: Z = np.zeros((10,20,3), dtype=int)
     ...: s0 = np.array([1,2,3])
     ...: s1 = np.array([4,5,6])
     ...: Z[1,2] = s0
     ...: Z[4,5] = s1
     ...: 

In [146]: np.where(((Z == S[:,None,None,:]).all(3)).any(0))
Out[146]: (array([1, 4]), array([2, 5]))

In [147]: np.where((np.in1d(Z,S).reshape(Z.shape)).all(2))
Out[147]: (array([1, 4]), array([2, 5]))

In [148]: np.column_stack((np.where(((Z == S[:,None,None,:]).all(3)).any(0))))
Out[148]: 
array([[1, 2],
       [4, 5]])

In [149]: np.column_stack((np.where((np.in1d(Z,S).reshape(Z.shape)).all(2))))
Out[149]: 
array([[1, 2],
       [4, 5]])