我有一个2D布尔数组,例如:
[[False, True, True],
[True, False, True],
[True, False, False],
[True, True, True]]
对于数组中的每一行,我想计算True的实例,并创建一个与原始数组形状相同的新的逐项数组,其中每个条目是行中所有先前True实例的总和。对于上面的例子,我想要的输出是:
[[0, 0, 1],
[0, 1, 1],
[0, 1, 1],
[0, 1, 2]]
有没有办法在Numpy中快速完成此操作,而不是像这样检查数组中的每个项目:
boolarr = np.array([[0, 1, 1], [1, 0, 1], [1, 0, 0], [1, 1, 1]], dtype=np.bool)
newarr = np.zeros(boolarr.shape)
for i, row in enumerate(boolarr):
for index, item in enumerate(row):
if item:
newarr[i][index+1:] += 1
我的阵列足够大(40 x 1260),速度是一个因素,因为这需要重复多次。
感谢。
答案 0 :(得分:2)
cumsum
是你的朋友!这是累计金额的缩写,你可以给它一个“轴”来处理,在你的情况下尝试运行:
np.cumsum(boolarr,axis=1) - boolarr
减法只取消“当前”值。
答案 1 :(得分:1)
基本上,您可以沿第二轴使用ndarray.cumsum
,并在开头添加全零列。因此,假设A
作为输入数组,您可以 -
np.column_stack((np.zeros((A.shape[0],1),dtype=A.dtype),A[:,:-1].cumsum(1)))
更高效的技术是用全零初始化输出数组,然后将 cumsumm-ed 值插入其中,如下所示 -
out = np.zeros(A.shape,dtype=int)
out[:,1:] = A[:,:-1].cumsum(1)
示例运行 -
In [30]: A
Out[30]:
array([[False, True, True],
[ True, False, True],
[ True, False, False],
[ True, True, True]], dtype=bool)
In [31]: np.column_stack((np.zeros((A.shape[0]),dtype=A.dtype),A[:,:-1].cumsum(1)))
Out[31]:
array([[0, 0, 1],
[0, 1, 1],
[0, 1, 1],
[0, 1, 2]])
In [32]: out = np.zeros(A.shape,dtype=int)
...: out[:,1:] = A[:,:-1].cumsum(1)
...:
In [33]: out
Out[33]:
array([[0, 0, 1],
[0, 1, 1],
[0, 1, 1],
[0, 1, 2]])