如何在Pandas中实现特殊负值序列计数:单非续计双非重置
Pandas实现带特殊规则的连续负值序列计数
我需要在Pandas DataFrame中为soilMoisture列生成sequenceNeg列,统计连续负值的序列,现有规则调整如下:
- 原规则:非负值记0并重置计数
- 新规则1:若单个非负值的前后均为负值,该位置仍计入连续计数(不重置,计数递增)
示例输入:soilMoisture = [-0.017, -0.015, -0.15, -0.020, -0.040, 0.11, -0.005, -0.050]
期望输出:sequenceNeg = [1,2,3,4,5,6,7,8] - 新规则2:若出现连续两个非负值,则重置序列计数,这两个非负值位置记0,后续负值重新开始计数
示例输入:soilMoisture = [-0.16, -0.7, -0.06, -0.07, -0.04, 0.11, 0.51, -0.09, -0.02]
期望输出:sequenceNeg = [1,2,3,4,5,0,0,1,2]
实现脚本
import pandas as pd import numpy as np # 构造测试用示例数据 data1 = {'soilMoisture': [-0.017, -0.015, -0.15, -0.020, -0.040, 0.11, -0.005, -0.050]} data2 = {'soilMoisture': [-0.16, -0.7, -0.06, -0.07, -0.04, 0.11, 0.51, -0.09, -0.02]} df1 = pd.DataFrame(data1) df2 = pd.DataFrame(data2) def compute_sequence_neg(df): # 标记所有非负值 is_non_neg = df['soilMoisture'] >= 0 # 标记连续非负值的位置:当前非负且前后至少一个非负(即连续2个及以上非负) is_consec_non_neg = is_non_neg & (is_non_neg.shift(1, fill_value=False) | is_non_neg.shift(-1, fill_value=False)) # 生成分组键:遇到连续非负的起始点则新建分组 reset_points = is_consec_non_neg & ~is_consec_non_neg.shift(1, fill_value=False) group_key = reset_points.cumsum() # 定义分组内的计数逻辑 def count_group(group): has_consec_non_neg = group['is_consec_non_neg'].any() if has_consec_non_neg: idx = group.index # 找到连续非负区间的首尾索引 consec_idx = idx[group['is_consec_non_neg']] first_consec = consec_idx[0] last_consec = consec_idx[-1] # 拆分区间并分别计数 res = pd.Series(0, index=idx) res.loc[idx[idx < first_consec]] = np.arange(1, len(idx[idx < first_consec])+1) res.loc[idx[idx > last_consec]] = np.arange(1, len(idx[idx > last_consec])+1) return res else: # 无连续非负,直接从1开始递增计数(包含单个非负的情况) return np.arange(1, len(group)+1) # 临时添加辅助列,完成计算后清理 df['is_non_neg'] = is_non_neg df['is_consec_non_neg'] = is_consec_non_neg df['sequenceNeg'] = df.groupby(group_key).apply(count_group).reset_index(level=0, drop=True) df.drop(['is_non_neg', 'is_consec_non_neg'], axis=1, inplace=True) return df # 运行测试 print("示例1结果:") print(compute_sequence_neg(df1)) print("\n示例2结果:") print(compute_sequence_neg(df2))
逻辑说明
- 关键位置标记:先识别所有非负值,再筛选出连续非负值的区间(即连续2个及以上的非负)
- 分组划分:以连续非负值的起始点为分界,将数据拆分为独立分组,每个分组包含连续非负块及其前后的负值块
- 分组计数:
- 不含连续非负的分组(包括单个非负值的情况):直接从1开始递增计数
- 含连续非负的分组:将连续非负位置设为0,之前的负值按顺序计数,之后的负值重新从1开始计数
内容的提问来源于stack exchange,提问作者Corey4005
相关产品推荐
相关产品推荐

