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

如何移除Pandas DataFrame中连续4个0值的行

解决连续4个月0值行的移除问题

你的原代码存在两个关键问题:

  1. 使用rolling(window=4)时未指定聚合逻辑,生成的是Rolling对象而非有效判断条件,导致后续的Total_rolling无法正确识别连续0值;
  2. 用shift标记移除行的逻辑只能覆盖部分行,没法把连续4个0的所有行都标记出来。

下面提供两种可靠的实现方案:

方案一:基于连续分组统计(直观易懂)

# 第一步:必须按ID和年月排序,保证时间序列连续性
df_next = df_next.sort_values(['ID', 'Year_Month'])

# 标记Total是否为0
df_next['is_zero'] = df_next['Total'] == 0

# 为每个连续的0序列分配唯一分组ID(非0行分组ID为0)
df_next['zero_group'] = df_next.groupby('ID')['is_zero'].apply(
    lambda x: x.cumsum() - x.cumsum().where(~x).ffill().fillna(0)
)

# 计算每个0分组的长度,标记需要移除的行
group_len = df_next.groupby(['ID', 'zero_group'])['is_zero'].transform('sum')
df_next['to_remove'] = df_next['is_zero'] & (group_len >= 4)

# 过滤并清理辅助列
df_filtered = df_next[~df_next['to_remove']].drop(['is_zero', 'zero_group', 'to_remove'], axis=1)

逻辑说明

  • 排序是核心前提:如果每个ID的行不是按时间顺序排列,连续值的判断完全失效;
  • zero_group通过累加标记,把连续的0归为同一分组,方便统计长度;
  • 最后只过滤掉那些属于长度≥4的0分组的所有行。

方案二:基于Rolling窗口(更简洁)

# 先排序
df_next = df_next.sort_values(['ID', 'Year_Month'])

# 用滚动窗口判断当前位置是否是连续4个0的最后一个位置
df_next['consec_zero'] = df_next.groupby('ID')['Total'].rolling(4, min_periods=4).apply(
    lambda x: (x == 0).all()
).reset_index(0, drop=True)

# 向前填充3次,把连续4个0的前3行也标记为需要移除
df_next['consec_zero'] = df_next.groupby('ID')['consec_zero'].ffill(limit=3).fillna(False)

# 过滤数据
df_filtered = df_next[~df_next['consec_zero']].drop('consec_zero', axis=1)

逻辑说明

  • rolling(4, min_periods=4)确保只有当窗口内有完整4个数据时才计算;
  • 窗口内全为0时返回1,否则返回NaN;
  • ffill(limit=3)把连续4个0的前3行也标记为True,这样整个连续序列都会被过滤;
  • 最后过滤掉标记为True的行即可。

验证方法

可以随机抽取存在连续0值的ID验证结果:

# 取一个有连续0的ID
test_id = df_next[df_next['Total'] == 0]['ID'].sample(1).iloc[0]
# 查看过滤后的数据
print(df_filtered[df_filtered['ID'] == test_id])

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 03:07:44