Pandas多列分组聚合过滤后,如何获取各组原始行?
问题解决方法
你当前代码的问题在于df[['a', 'b']].isin(original_index_filtered)是逐元素检查是否存在于索引的任意层级,而非匹配整行的(a,b)组合,因此得到全NaN的错误结果。以下是两种正确的解决方式:
解法1:使用groupby.transform直接标记过滤(推荐)
这种方法无需处理索引,直接在原数据上生成组内的匹配标记,代码更简洁高效:
import pandas as pd df = pd.DataFrame( { 'a': ['A', 'A', 'B', 'B', 'B', 'C'], 'b': ['A', 'A', 'B', 'B', 'B', 'C'], 'hole': [True, True, True, False, False, True] } ) # 为每行生成对应组的hole是否全为True的标记 df['valid_group'] = df.groupby(['a', 'b'])['hole'].transform(lambda x: all(x)) # 过滤有效组的行并移除临时列 original_filtered = df[df['valid_group']].drop(columns='valid_group') print(original_filtered)
输出结果:
a b hole 0 A A True 1 A A True 5 C C True
解法2:转换索引格式匹配整行组合
如果需要单独获取有效(a,b)组对,可以将多级索引转为元组列表,再匹配整行的组合:
import pandas as pd df = pd.DataFrame( { 'a': ['A', 'A', 'B', 'B', 'B', 'C'], 'b': ['A', 'A', 'B', 'B', 'B', 'C'], 'hole': [True, True, True, False, False, True] } ) groups = df.groupby(['a', 'b']) agg_groups = groups.agg({'hole': lambda x: all(x)}) # 将有效组的多级索引转为元组列表 valid_pairs = list(agg_groups[agg_groups['hole']].index) # 把每行的a、b转为元组,检查是否在有效列表中 original_filtered = df[df[['a', 'b']].apply(tuple, axis=1).isin(valid_pairs)] print(original_filtered)
输出结果与解法1一致。
内容的提问来源于stack exchange,提问作者Gulzar
相关产品推荐
相关产品推荐

