我有numpy数组
arr = np.array([[0, 0, 2, 5, 0, 0, 1, 8, 0, 3, 0],
[1, 2, 0, 0, 0, 0, 5, 7, 0, 0, 0],
[8, 5, 3, 9, 0, 1, 0, 0, 0, 0, 1]])
我需要这样的结果数组:
[[0, 0, 0, 0, 7, 0, 0, 0, 9, 0, 3]
[0, 0, 3, 0, 0, 0, 0, 0, 12, 0, 0]
[0, 0, 0, 0, 25, 0, 1, 0, 0, 0, 0]]
发生什么事了?
我们沿着行前进,如果行中的元素是0,那么我们前进到下一个元素,如果不是0,那么我们对元素求和直到满足0,一旦满足0,那么我们用结果和替换它(也用0替换初始非零数字
我已经知道如何使用循环来实现这一点,但是对于大量的行,它在时间上效果不好,所以我需要numpy方法中的时间效率解决方案。
更新
这是一个尝试
zero_el = arr == 0
>>> np.where(zero_el, arr.cumsum(axis=1), 0)
[[ 0 0 0 0 7 7 0 0 16 0 19]
[ 0 0 3 3 3 3 0 0 15 15 15]
[ 0 0 0 0 25 0 26 26 26 26 0]]
3条答案
按热度按时间e4yzc0pl1#
首先,我们要找到数组中零与非零相邻的位置。
现在,我们可以使用
np.add.reduceat
来添加元素。不幸的是,reduceat
需要一个一维索引的列表,所以我们将不得不稍微使用一些形状。计算扁平数组中rr, cc
的等效索引很容易:我们希望从 * 每一行的开头 * 开始进行约简,因此我们将创建一个
row_starts
来混合上面计算的索引:现在,在展平的输入数组上调用
np.add.reduceat
,减少到reduce_indices
现在我们有了总数,我们需要将它们赋给一个零数组,注意
totals
的第0
个元素需要转到reduce_indices
的第1
个索引,而totals
的最后一个元素要被丢弃:这给出了预期结果:
6jygbczu2#
我们可以使用2个for循环来求解,在每一行我们定义current_sum,如果number为零,我们将current_sum赋值给number并重置current_sum;如果number不为零,则将0赋给number,并且递增current_sum。
编辑:首先对不起,我没有意识到你想要一个高效的解决方案。我们可以使用numba来加速for循环。它真的很简单,功能也很强大。下面是代码:
函数在第一次运行时很慢,因为它理解输入和函数并创建机器码,但在那之后它真的很快。我希望它对你的情况来说足够快。
acruukt93#
可能比in循环长......但让我用单数组来演示: