我正在使用 Python 2.7 和 NumPy 来处理大型布尔值数组。
我有一个数组A,就像这样:
>>> A
array([[[False, False, True, True, True],
[False, False, False, True, True],
[False, False, True, True, True],
[False, False, False, True, True],
[False, False, False, False, True]],
[[False, True, True, True, True],
[False, True, True, True, True],
[False, False, True, True, True],
[False, True, True, True, True],
[False, False, True, True, True]]])
我必须把它转换成这样的布尔数组:
>>> B
array([[[True, False, True, True, True],
[True, True, False, True, True],
[True, False, True, True, True],
[True, True, False, True, True],
[True, True, True, False, True]],
[[False, True, True, True, True],
[False, True, True, True, True],
[True, False, True, True, True],
[False, True, True, True, True],
[True, False, True, True, True]]])
因此,我们的想法是每行的最后False
值应保留,任何其他值应为True
。
我需要创建它才能将它用作另一个数组的掩码。
有没有办法用 NumPy 而不使用for
循环(这很慢)?
答案 0 :(得分:3)
这是一种适用于您的数组的方法(也适用于具有更多混合行的数组,例如[F, T, T, F, T]
):
>>> x = 4 - np.argmin(A[:,:,::-1], axis=2)[:,:,np.newaxis]
>>> (np.arange(5) * np.ones_like(A)) != x
array([[[ True, False, True, True, True],
[ True, True, False, True, True],
[ True, False, True, True, True],
[ True, True, False, True, True],
[ True, True, True, False, True]],
[[False, True, True, True, True],
[False, True, True, True, True],
[ True, False, True, True, True],
[False, True, True, True, True],
[ True, False, True, True, True]]], dtype=bool)
说明:
翻转A
上的数组axis=2
并在该轴上使用argmin
以获取第一个False
值的索引。
我们需要知道False
中A
的最后一次出现的索引(不是翻转数组中的第一次出现)。这是数组深度(即5)减去1的值减去前一步骤中找到的索引。
通过添加新轴(A
)使这个新的索引数组与axis=2
兼容。调用这个新的索引数组x
。
构建与A
相同维度的数组,其中axis=2
的每一行都是np.arange(5)
。通过使用x
测试此构造数组的不等式,可以找到所需的布尔数组。
答案 1 :(得分:3)
您也可以使用xor运算符^
来实现此目的。简单地将数组“leftshift”为1,并向右添加True
值,然后xor为新数组和旧数组:
A = np.array([[False, False, True, True, True],
[False, False, False, True, True],
[False, False, True, True, True],
[False, False, False, True, True],
[False, False, False, False, True]])
X = np.hstack((A[:,1:],
np.array(np.ones((A.shape[0], 1)), dtype=np.bool))))
>>> array([[False, True, True, True, True],
[False, False, True, True, True],
[False, True, True, True, True],
[False, False, True, True, True],
[False, False, False, True, True]])
np.invert(A ^ X)
>>> array([[True, False, True, True, True],
[True, True, False, True, True],
[True, False, True, True, True],
[True, True, False, True, True],
[True, True, True, False, True]])
此功能仅在保留所有False
值且仅后跟True
值的情况下有效。
答案 2 :(得分:1)
如果反转数组,可以使用numpy.nonzero
查找所有(最初)错误条目,然后从中获取每行中的最后一个。然后,您可以使用它来构建掩码数组。
答案 3 :(得分:0)
这是一个简单的问题。您需要选择每一行。使用 np.where()找到 False 的位置,并将 True 放在除索引[ - 表示的最后一个]之外的其他位置1] 即可。这是在下面给出的代码中完成的:
>>> import numpy as np
>>> A=np.array([[[False, False, True, True, True],
[False, False, False, True, True],
[False, False, True, True, True],
[False, False, False, True, True],
[False, False, False, False, True]],
[[False, True, True, True, True],
[False, True, True, True, True],
[False, False, True, True, True],
[False, True, True, True, True],
[False, False, True, True, True]]])
>>> for mat in A:
opmat=[]
for arr in mat:
index=np.where(arr==False)
arr[index[0][:-1]]=True
opmat.append(arr)
out.append(opmat)
>>> out=np.array(out)
>>> out
array([[[ True, False, True, True, True],
[ True, True, False, True, True],
[ True, False, True, True, True],
[ True, True, False, True, True],
[ True, True, True, False, True]],
[[False, True, True, True, True],
[False, True, True, True, True],
[ True, False, True, True, True],
[False, True, True, True, True],
[ True, False, True, True, True]]], dtype=bool)