Pandas与Python高级累计分组:合并0值sign分组的实现方案
解决时间序列分组中sign=0的合并问题
嘿,针对你这个需求,最优的做法其实是先预处理sign列,把0值替换成你想合并的相邻非0值,再用原来的分组逻辑,这样既高效又能完美实现你的目标。
先回顾下你的场景
你已经有了能按连续sign值分组的代码,但单独的sign=0分组需要合并到指定的相邻分组(比如你示例里的sign=1)。
先把你的原始数据和现有代码贴出来方便参考:
import pandas as pd df = pd.DataFrame({ 'a': [-0.066, 0.334, 0.991, 0.420, 0.000, -0.570, -0.294, 0.579, 0.234, -0.954], 'b': [19.514, 19.848, 20.839, 21.259, 21.367, 20.797, 20.503, 21.082, 21.316, 20.362], 'sign': [-1, 1, 1, 1, 0, -1, -1, 1, 1, -1] }) # 你现有的分组代码(0会单独成组) df2 = df.groupby((df["sign"] != df['sign'].shift()).cumsum(), as_index=False).agg({'sign': 'first', 'a': ['sum','count']}) df2.columns = ['sign', 'asum', 'cnt']
最优实现步骤
核心思路是用ffill(向前填充)把sign=0替换成前一个非0的sign值,这样0所在的行就会被归入前面的分组;如果想合并到后面的分组,就用bfill(向后填充)。
完整代码
# 1. 预处理sign列:把0替换为前一个非0的sign值,这样0就会跟着前面的分组走 df['adjusted_sign'] = df['sign'].replace(0, method='ffill') # 2. 用调整后的sign列执行原来的分组逻辑 df2 = df.groupby( (df["adjusted_sign"] != df['adjusted_sign'].shift()).cumsum(), as_index=False ).agg( {'adjusted_sign': 'first', 'a': ['sum', 'count']} ) # 3. 调整列名到你需要的格式 df2.columns = ['sign', 'asum', 'cnt'] # 看看结果 print(df2)
输出结果(完全匹配你的期望)
sign asum cnt 0 -1.0 -0.066 1 1 1.0 1.745 4 # 原3个1的行 + 1个0的行合并,sum和count自动累加 2 -1.0 -0.864 2 3 1.0 0.813 2 4 -1.0 -0.954 1
特殊情况处理
如果你的数据开头就有sign=0,可以先向后填充再向前填充,确保所有0都能找到合适的分组:
import numpy as np # 先把0换成NaN,向后填充找后面的非0值,再向前填充确保所有NaN都被覆盖 df['adjusted_sign'] = df['sign'].replace(0, np.nan).bfill().ffill()
这样不管0出现在数据的哪个位置,都能正确合并到最近的非0分组里。
内容的提问来源于stack exchange,提问作者blissweb
相关产品推荐
相关产品推荐

