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

如何用Pandas按分组对非零值进行自动递增编号?

数据
Group  Value
0     A      2
1     A      4
2     B      1
3     B      3
4     B      0
5     C      0
6     C      5
数据2
ts_code    bkb_close
date        
2020-09-30  399106.SZ   0.0000
2020-10-09  399106.SZ   2215.9609
2020-10-12  399106.SZ   2289.3570
2020-10-13  399106.SZ   0.0000
2020-10-14  399106.SZ   0.0000
2020-10-15  399106.SZ   0.0000
2020-10-16  399106.SZ   0.0000
2020-10-19  399106.SZ   0.0000
2020-10-20  399106.SZ   0.0000
2020-10-21  399106.SZ   0.0000
2020-10-22  399106.SZ   0.0000
2020-10-23  399106.SZ   0.0000
2020-10-26  399106.SZ   0.0000
2020-10-27  399106.SZ   2223.9227
2020-10-28  399106.SZ   2239.1080
2020-10-28  399300.SZ   4737.2718
2020-10-29  399106.SZ   2249.5738
2020-10-29  399300.SZ   4772.9198
2020-10-30  399106.SZ   0.0000
2020-10-30  399300.SZ   0.0000
2020-11-02  399300.SZ   4720.8313
2020-11-02  399106.SZ   0.0000
2020-11-03  399106.SZ   2255.0834
2020-11-03  399300.SZ   0.0000
目标与预期结果

新增列C,按Group列分组后,基于Value列对非零值进行自动递增编号;零值对应的C列设为NaN,递增时跳过零值。

预期结果:

Group  Value  C 
0     A      2    1
1     A      4    2
2     B      1    1
3     B      3    2
4     B      0    NaN
5     C      0    NaN
6     C      5    1
尝试代码
df['C']=df.groupby('Group').transform(lambda x: x[x>0].cumsum()+1)
问题分析与解决方案

当前代码的问题在于:用cumsum()对非零值求和而非计数,且x[x>0]过滤零值后会导致transform的索引不匹配,最终结果不符合预期。

以下是两种可行的解决方案:

方案一:分步实现(清晰易懂)

import pandas as pd

# 1. 标记非零值为1,零值为0
df['non_zero_flag'] = df['Value'].gt(0).astype(int)
# 2. 按Group分组后累计计数
df['C'] = df.groupby('Group')['non_zero_flag'].cumsum()
# 3. 将原Value为0的行的C列设为NaN
df.loc[df['Value'] == 0, 'C'] = pd.NA
# 4. 移除临时标记列(可选)
df = df.drop('non_zero_flag', axis=1)

方案二:简洁写法(一行完成)

df['C'] = df.groupby('Group')['Value'].apply(
    lambda x: x.gt(0).cumsum().where(x.gt(0))
)

执行任意一种方案后,即可得到符合预期的结果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 05:05:40