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

如何基于特定值标记DataFrame列中的降雨事件

问题描述

现有一个包含多列的DataFrame,重点处理Rain_Stream['rain_event']列,原始数据示例如下(实际数据更长):

Rain_Stream['rain_event'] = [nan, nan, nan, nan, nan, nan, nan, 1, nan, nan, nan, nan, nan, nan, nan, nan, 2, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, 1, nan, nan, nan, nan, nan, nan, 2, nan, nan, nan, nan, nan, nan, nan, 1, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, 2, nan, nan, nan, nan, nan, 1, nan, nan, nan, nan, nan, nan, 2, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan]

其中1标记降雨事件的开始,2标记降雨事件的结束。期望处理后,该列变为:

Rain_Stream['rain_event'] = [nan, nan, nan, nan, nan, nan, nan, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, 2, 2, 2, 2, 2, 2, 2, 2, nan, nan, nan, nan, nan, nan, nan, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, nan, nan, nan, nan, nan, 4, 4, 4, 4, 4, 4, 4, 4, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan]

要求:每个降雨事件按出现顺序用对应序号标记,从开始的1到结束的2之间的所有值都替换为该事件的序号(原1和2也需替换),事件之间保留nan或0均可。

已尝试掩码、向前填充(ffill)等方法但未成功,尝试的代码如下:

# 尝试1
mask = Rain_Stream['begin_rain_checked'] == 1
Rain_Stream['rain_event'] = mask.cumsum()
mask = Rain_Stream['end_rain_checked'] == 2
Rain_Stream['rain_event'] = mask.nan

# 尝试2
Rain_Stream['rain_event'] = Rain_Stream['rain_event'].ffill()
Rain_Stream['rain_event'] = Rain_Stream['rain_event'].mask(Rain_Stream['rain_event'].duplicated())
Rain_Stream['rain_event'] = Rain_Stream['rain_event'].ffill()
解决方案

可以通过以下步骤实现需求:

  • 标记降雨事件的起始点:统计所有1出现的次数,生成事件序号的基础
  • 识别事件区间:判断每行是否处于某个降雨事件的区间内(起始后、结束前)
  • 填充事件序号:将事件区间内的行统一赋值为对应事件的序号
  • 处理结束点:确保结束点2也被替换为对应事件的序号

具体代码实现:

import pandas as pd
import numpy as np

# 复制原列避免修改原始数据,若需直接覆盖原列,替换为'rain_event'即可
Rain_Stream['rain_event_processed'] = Rain_Stream['rain_event'].copy()

# 生成每个事件的序号:每遇到1就递增1
event_num = Rain_Stream['rain_event'].eq(1).cumsum()

# 标记哪些行处于事件区间内(起始累计数≠结束累计数)
in_event = Rain_Stream['rain_event'].eq(1).cumsum() != Rain_Stream['rain_event'].eq(2).cumsum()

# 给事件区间内的行填充对应序号,非区间行保留nan
Rain_Stream['rain_event_processed'] = np.where(in_event, event_num, np.nan)

# 处理结束点2,替换为对应事件序号
end_positions = Rain_Stream['rain_event'] == 2
Rain_Stream.loc[end_positions, 'rain_event_processed'] = event_num[end_positions]

代码说明

  • event_num:通过eq(1).cumsum()统计起始点1的出现次数,得到每个事件的唯一序号
  • in_event:对比起始点和结束点的累计次数,精准锁定每个降雨事件的区间范围
  • np.where:快速实现区间内赋值、非区间保留nan的逻辑
  • 单独处理结束点,确保2被正确替换为对应事件序号,避免遗漏

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 09:14:54