如何按特定规则调整Pandas序列中连续零后的非零值
如何按特定规则调整Pandas序列中连续零后的非零值
嘿,你已经做了很棒的铺垫工作——计算连续零的计数这部分完全正确!接下来咱们把这个结果和前一个非零块的信息结合起来,就能实现你想要的调整规则了。
先回顾下你的需求:对于连续零之后出现的非零值,需要用公式 前一个非零值 - 前面零的总数量 + 当前值 来更新。咱们一步步来实现:
1. 先准备好原始数据
你已经给出了创建Series的代码,这里稍微调整下确保类型正确:
import pandas as pd d = {'1': 1, '2': 2, '3': 3, '4':4, '5':0, '6':0, '7':1, '8':2, '9':3, '10':0, '11':0, '12':0, '13':0, '14':1, '15':2} ser = pd.Series(data=d, dtype=int)
2. 分组标记连续的零/非零块
首先用ser.ne(0).cumsum()生成分组键,这样连续的非零或连续的零会被分到同一个组里:
group_key = ser.ne(0).cumsum()
3. 提取分组的关键信息
我们需要每个分组的三个信息:是否是零组、组的长度、非零组的最后一个值(作为下一个非零组的“前一个非零值”):
group_info = ser.groupby(group_key).agg( is_zero=('value', lambda x: x.eq(0).all()), length=('value', 'size'), last_value=('value', 'last') ).reset_index()
4. 计算每个非零组的调整参数
遍历分组信息,跟踪前一个非零值和累计的零数量,把每个需要调整的非零组的参数存起来:
prev_non_zero = None zero_count_before = 0 adjust_params = {} for idx, row in group_info.iterrows(): if row['is_zero']: # 遇到零组,累加长度到零计数 zero_count_before += row['length'] else: if prev_non_zero is not None: # 非零组,记录调整需要的参数 adjust_params[row['index']] = (prev_non_zero, zero_count_before) # 更新前一个非零值,重置零计数 prev_non_zero = row['last_value'] zero_count_before = 0
5. 应用规则调整数值
最后定义一个调整函数,对每个分组应用规则:
def adjust_values(x): group_id = x.name if group_id not in adjust_params: # 第一个非零组,保持原数值不变 return x prev_val, zero_cnt = adjust_params[group_id] return prev_val - zero_cnt + x # 应用调整得到结果 result = ser.groupby(group_key).apply(adjust_values)
验证结果
打印result就能得到你想要的格式:
1 1 2 2 3 3 4 4 5 0 6 0 7 3 8 4 9 5 10 0 11 0 12 0 13 0 14 2 15 3 dtype: int64
这个逻辑完美匹配你给出的规则:比如第7行的3就是4-2+1,第14行的2就是5-4+1,完全符合预期!
备注:内容来源于stack exchange,提问作者prem
相关产品推荐
相关产品推荐

