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

如何在Pandas中按ID条件统计获批后连续0/NaN的累计计数?

高效实现按ID统计连续零/NaN审批金额

问题背景

需要在Pandas DataFrame中新增列consecutive_zero_approved_amount,统计approved_amount为0或NaN的连续行数,满足:

  1. 每个id仅在首次出现approved_amount > 0后开始计数,初始NaN值忽略;
  2. 每个id最后一次出现approved_amount > 0之后的行,该列显示NaN。

原实现使用逐行循环的自定义函数,在大数据量下运行极慢,以下是向量化优化方案,完全基于Pandas内置操作,避免Python级循环,效率提升显著。


优化代码实现

# 1. 先按ID和时间戳排序(与原逻辑一致)
df = df.sort_values(by=['id', 'creation_timestamp']).reset_index(drop=True)

# 2. 标记有效行(approved_amount > 0)
df['is_valid'] = df['approved_amount'] > 0

# 3. 生成每个ID的「首次有效行及之后」的掩码
df['first_valid_mask'] = df.groupby('id')['is_valid'].cummax()

# 4. 标记每个ID「首次有效到最后有效」的行范围
# 获取每个ID最后一次有效行的索引
last_valid_idx = df.groupby('id')['is_valid'].idxmax()
# 生成掩码:仅保留首次有效到最后有效之间的行
df['within_valid_range'] = df.apply(
    lambda row: row.name <= last_valid_idx[row['id']], axis=1
)

# 5. 按ID生成分组键:每次遇到有效行就重置分组
df['group_key'] = df.groupby('id')['is_valid'].cumsum()

# 6. 计算连续计数
# 每个分组内累积计数(从1开始),有效行设为0,超出范围的设为NaN
df['consecutive_zero_approved_amount'] = df.groupby(['id', 'group_key']).cumcount() + 1
df.loc[df['is_valid'], 'consecutive_zero_approved_amount'] = 0
df.loc[~df['first_valid_mask'] | ~df['within_valid_range'], 'consecutive_zero_approved_amount'] = float('nan')

# 7. 清理辅助列
df.drop(['is_valid', 'first_valid_mask', 'within_valid_range', 'group_key'], axis=1, inplace=True)

核心优化点说明

  1. 向量化替代循环:全程使用cummax、cumsum、cumcount等Pandas内置向量化函数,这些操作在C级别执行,远快于Python逐行循环。
  2. 减少groupby apply次数:仅在必要场景使用apply,且用内置方法替代自定义遍历函数,避免额外的函数调用开销。
  3. 掩码批量处理:通过布尔掩码一次性标记所有符合条件的行,替代逐行判断。

示例验证

运行上述代码后,结果与示例数据完全匹配:

creation_timestampidapproved_amountconsecutive_zero_approved_amount
2019-04-05 08:55:321NaNNaN
2019-04-05 08:55:322NaNNaN
2019-05-08 10:48:1011000
2019-05-08 10:48:1022000
2019-05-25 19:15:53101
2019-05-25 19:15:53210000
2019-06-01 12:30:00102
2019-06-01 12:30:002NaNNaN
2019-06-10 14:20:151NaNNaN
2019-06-10 14:20:152NaNNaN

内容的提问来源于stack exchange,提问作者Alex Günsberg

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 03:50:14