我正在寻找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
等于s0
或s1
。
到目前为止,
argwhere
返回s0
中Z
中的一个元素所在的每个匹配项:
> 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
。
有什么想法吗?
答案 0 :(得分:2)
np.in1d
会压缩其输入。因此,您可以提供Z
和s0
,s1
的堆叠版本,为我们提供一个布尔数组,可以将其重新整形为与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]])