如何在Pandas DataFrame中按条件删除后续记录及分组处理
问题描述
基础需求
我创建了如下Pandas DataFrame:
import pandas as pd ds1 = {'col1':[1,2,3,4,5,6,7], "col2" : [1,1,0,1,1,1,1]} df1 = pd.DataFrame(data=ds1)
输出内容:
col1 col2 0 1 1 1 2 1 2 3 0 3 4 1 4 5 1 5 6 1 6 7 1
需要实现:一旦col2的值为0,就删除该记录之后的所有行,无论后续行的值如何。处理后结果如下:
col1 col2 0 1 1 1 2 1 2 3 0
另一个示例:
import pandas as pd ds1 = {'col1':[1,2,3,4,5,6,7], "col2" : [0,0,0,1,1,1,1]} df1 = pd.DataFrame(data=ds1)
处理后结果应为:
col1 col2 0 1 0
分组需求
还有一个附加场景:
import pandas as pd ds1 = {'col1':[1,1,1,1,1,1,1, 2,2,2,2,2,2,2], "col2" : [1,1,0,1,1,1,1,1,1,0,1,1,1,1]} df1 = pd.DataFrame(data=ds1)
输出内容:
col1 col2 0 1 1 1 1 1 2 1 0 3 1 1 4 1 1 5 1 1 6 1 1 7 2 1 8 2 1 9 2 0 10 2 1 11 2 1 12 2 1 13 2 1
需要按col1分组,在每个组内执行上述相同的条件删除操作,处理后结果如下:
col1 col2 0 1 1 1 1 1 2 1 0 7 2 1 8 2 1 9 2 0
解决方案
单个DataFrame处理
核心逻辑是找到col2中第一个值为0的行索引,保留从开头到该索引的所有行;若没有0值则保留全部行。
实现代码:
import pandas as pd # 创建示例DataFrame ds1 = {'col1':[1,2,3,4,5,6,7], "col2" : [1,1,0,1,1,1,1]} df1 = pd.DataFrame(data=ds1) # 定位第一个col2为0的索引 first_zero_idx = df1[df1['col2'] == 0].index.min() # 截取数据 df_processed = df1.loc[:first_zero_idx] if pd.notna(first_zero_idx) else df1.copy() print(df_processed)
测试第二个示例(col2首值为0):
ds2 = {'col1':[1,2,3,4,5,6,7], "col2" : [0,0,0,1,1,1,1]} df2 = pd.DataFrame(data=ds2) first_zero_idx = df2[df2['col2'] == 0].index.min() df_processed = df2.loc[:first_zero_idx] if pd.notna(first_zero_idx) else df2.copy() print(df_processed)
输出符合预期。
分组后处理
通过groupby结合自定义函数,对每个分组执行上述截断逻辑:
实现代码:
import pandas as pd # 创建分组示例DataFrame ds3 = {'col1':[1,1,1,1,1,1,1, 2,2,2,2,2,2,2], "col2" : [1,1,0,1,1,1,1,1,1,0,1,1,1,1]} df3 = pd.DataFrame(data=ds3) # 定义分组处理函数 def truncate_after_first_zero(group): first_zero_idx = group[group['col2'] == 0].index.min() if pd.notna(first_zero_idx): return group.loc[:first_zero_idx] else: return group.copy() # 分组应用函数 df_grouped_processed = df3.groupby('col1', group_keys=False).apply(truncate_after_first_zero) print(df_grouped_processed)
执行后输出结果与需求完全匹配。
补充说明
- 若
col2中无0值,代码会保留原数据,逻辑自洽; index.min()确保定位的是第一个出现0的位置,不受后续0值干扰;group_keys=False避免结果生成层级索引,保持原数据结构简洁。
内容的提问来源于stack exchange,提问作者Giampaolo Levorato
相关产品推荐
相关产品推荐

