如何用Python 3.x的Pandas groupby查找DataFrame冗余分组
问题分析与修正
你的代码核心错误在于:将“当前分组的所有值被之前分组包含”理解为“当前分组是之前某一个分组的子集”,但正确的定义应该是“当前分组的所有元素都存在于之前所有分组的并集中”(即没有新元素)。
正确代码实现
import pandas as pd df = pd.DataFrame({'a':[1,1,1,2,2,3,4,4,4,5,5,5,5], 'b':[1001,1002,1232,1001,1002,3002,1021,2021,4000,1002,1002,2031,120]}) # 获取每个分组的b值去重集合 groups = [set(g['b']) for _, g in df.groupby('a')] total_covered = set() counter = 0 # 处理第一个分组,初始化已覆盖集合 total_covered.update(groups[0]) # 遍历后续分组 for group in groups[1:]: # 检查当前分组是否完全被之前的所有分组覆盖 if group.issubset(total_covered): counter += 1 # 更新已覆盖集合,加入当前分组的元素 total_covered.update(group) print(counter) # 输出1,符合预期
Pandas风格的简洁实现
可以利用groupby结合累积并集来实现,更符合Pandas的使用习惯:
import pandas as pd from itertools import accumulate def union(a, b): a.update(b) return a.copy() df = pd.DataFrame({'a':[1,1,1,2,2,3,4,4,4,5,5,5,5], 'b':[1001,1002,1232,1001,1002,3002,1021,2021,4000,1002,1002,2031,120]}) # 获取每个分组的b值唯一集合,转为DataFrame group_sets = df.groupby('a')['b'].apply(set).reset_index(name='b_set') # 生成每个分组对应的之前所有分组的累积并集 cumulative_unions = list(accumulate(group_sets['b_set'], union, initial=set())) group_sets['prev_covered'] = cumulative_unions[:-1] # 统计冗余分组数量 redundant_count = group_sets['b_set'].apply(lambda x: x.issubset(group_sets['prev_covered'])).sum() print(redundant_count) # 输出1
补充说明
- 累积并集的作用是维护到当前分组为止,之前所有分组出现过的所有唯一值。
- 检查
group.issubset(total_covered)可以准确判断当前分组是否没有新元素,完全符合题目中“冗余分组”的定义。
内容的提问来源于stack exchange,提问作者longira
相关产品推荐
相关产品推荐

