Numpy:在2D bool数组中以项目方式快速计算True实例

时间:2015-10-21 09:25:52

标签: python arrays numpy

我有一个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),速度是一个因素,因为这需要重复多次。

感谢。

2 个答案:

答案 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]])