如何用Pandas按特殊规则对DataFrame进行分组?
用Pandas实现指定分组需求的方案
当然可以完美实现你的需求!你之前尝试的连续值分组思路没有结合ID的分组逻辑,所以没法精准定位每个ID内的目标行。我们可以通过按ID分组后逐个处理每组数据的方式,精准划分出你要的三个分组。
先准备好基础数据
首先先把你的数据构造出来:
import pandas as pd data = { 'ID': [100, 100, 100, 100, 200, 200, 200, 200, 200, 300, 300, 300, 300, 300], 'value': [False, False, True, False, False, True, True, True, False, False, False, True, True, False], } df = pd.DataFrame(data, columns=['ID','value'])
实现三个分组的核心逻辑
我们可以通过groupby('ID')遍历每个ID组,然后针对每组计算关键位置,再筛选出对应行:
1. 分组1:每个ID中首个True行之前的所有False行
对于每个ID组,先找到第一个True出现的位置,然后筛选出该位置之前的所有False行:
# 定义函数处理单个ID组 def get_group1(group): first_true_idx = group['value'].idxmax() # 获取组内第一个True的索引 # 筛选索引小于first_true_idx且value为False的行 return group[(group.index < first_true_idx) & (group['value'] == False)] group1 = df.groupby('ID').apply(get_group1).reset_index(drop=True) print("分组1结果:") print(group1)
2. 分组2:每个ID中最后一个True行之后的所有False行
类似地,找到每个组内最后一个True的位置,然后筛选该位置之后的False行:
def get_group2(group): # 反转组内value,找到第一个True的索引,就是原组最后一个True的位置 last_true_idx = group['value'][::-1].idxmax() # 筛选索引大于last_true_idx且value为False的行 return group[(group.index > last_true_idx) & (group['value'] == False)] group2 = df.groupby('ID').apply(get_group2).reset_index(drop=True) print("\n分组2结果:") print(group2)
3. 分组3:所有True行
这个最简单,直接筛选整个DataFrame中value为True的行即可:
group3 = df[df['value'] == True].reset_index(drop=True) print("\n分组3结果:") print(group3)
运行结果验证
执行上述代码后,你会得到完全符合需求的三个分组:
- 分组1包含ID100的前2行False、ID200的第1行False、ID300的前2行False
- 分组2包含ID100的最后1行False、ID200的最后1行False、ID300的最后1行False
- 分组3包含所有标记为True的行
补充说明
如果你的DataFrame索引不是默认的连续整数,也可以改用组内的相对位置(比如用cumcount()生成组内序号)来判断,逻辑是一样的,只需要把索引替换成组内序号即可。
内容的提问来源于stack exchange,提问作者Ford1892
相关产品推荐
相关产品推荐

