You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

寻求基于Numpy的遇0重置向量化累积求和实现方案

我懂你想要的是完全基于NumPy的向量化方案来实现「遇到0就重置的累积求和」——先看你的例子:输入ar = np.array([0,1,0,1,1,0,1,0]),期望输出np.array([0,1,0,1,2,0,1,0])。你现有的两种方法要么依赖pandas分组,要么需要循环拆分数组,确实不够纯粹的向量化。这里给你两个高效的纯NumPy向量化实现:

方法1:累积和减去最近重置点(最优方案)

这个思路的核心是用全局累积和,减去每个位置最近一次0对应的累积值,就能得到从最近的0开始的局部累积和:

import numpy as np

ar = np.array([0,1,0,1,1,0,1,0])

# 计算全局累积和
cumsum_total = np.cumsum(ar)
# 找到所有0的位置,加上开头的0作为初始重置点
zero_positions = np.concatenate([[0], np.where(ar == 0)[0]])
# 提取每个重置点对应的全局累积和
reset_values = cumsum_total[zero_positions]
# 给每个元素分配分组ID(到当前位置为止出现的0的次数)
group_ids = np.cumsum(ar == 0)
# 用全局累积和减去对应分组的重置值,得到结果
result = cumsum_total - reset_values[group_ids]

print(result)  # 输出: [0 1 0 1 2 0 1 0]

这个方案完全用NumPy内置的向量化函数实现,没有任何循环或分组操作,处理大规模数组时效率拉满。

方法2:自定义累积操作

如果你更倾向于直观的逻辑,可以用np.frompyfunc把自定义的重置累积逻辑转为通用函数,再做累积计算:

import numpy as np

def reset_cumsum(arr):
    # 自定义累积规则:遇到0就重置,否则累加前值
    def accumulate_rule(prev_sum, current_val):
        return current_val if current_val == 0 else prev_sum + current_val
    
    # 把Python函数转为NumPy可处理的ufunc,再执行累积
    ufunc = np.frompyfunc(accumulate_rule, 2, 1)
    return ufunc.accumulate(arr, dtype=object).astype(np.int64)

ar = np.array([0,1,0,1,1,0,1,0])
print(reset_cumsum(ar))  # 输出: [0 1 0 1 2 0 1 0]

这个方法没有显式循环,依赖NumPy的累积机制,也算纯向量化实现,逻辑更贴近手动计算的思路。


对比你现有的方法

你提到的两种方案虽然可行,但都不算完全向量化:

  1. Pandas分组法:
import pandas as pd
s = pd.Series(ar)
data = s.groupby(s.eq(0).cumsum()).cumsum().tolist()

代码简洁,但底层依赖分组遍历,本质是隐式循环,且需要引入pandas库。

  1. np.split拆分法:
    你没写完的代码大概是这种逻辑:
def intervaled_cumsum(ar):
    zero_indices = np.where(ar == 0)[0]
    splits = np.split(ar, zero_indices)
    result = []
    for split in splits:
        result.extend(np.cumsum(split))
    return np.array(result)

需要显式循环处理每个拆分后的子数组,当数组规模很大时,循环会成为性能瓶颈。

内容的提问来源于stack exchange,提问作者user9653473

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 07:08:12