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

如何在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))

逻辑说明

  1. 关键位置标记:先识别所有非负值,再筛选出连续非负值的区间(即连续2个及以上的非负)
  2. 分组划分:以连续非负值的起始点为分界,将数据拆分为独立分组,每个分组包含连续非负块及其前后的负值块
  3. 分组计数:
    • 不含连续非负的分组(包括单个非负值的情况):直接从1开始递增计数
    • 含连续非负的分组:将连续非负位置设为0,之前的负值按顺序计数,之后的负值重新从1开始计数

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 01:31:21