如何在Pandas中筛选分组后col列集合大小>1的行?
解决DataFrame分组后筛选col列集合大小大于1的行的问题
你想筛选出按concat列分组后,组内col列值的集合大小大于1的所有行对吧?你之前的代码报错是因为lambda表达式缺少else分支,而且这种写法也没法直接帮你筛选原数据,我来帮你修正一下:
分步解决方案
首先,我们需要先找出哪些分组符合条件(即组内col的集合长度>1),再用这些分组去过滤原DataFrame:
- 构建示例数据(和你的代码一致):
import pandas as pd df = pd.DataFrame({'col': [1, 2, 3], 'a': [41, 4, 5], 'b': [3, 13, 6]}) df['concat'] = df['a'].astype(str) + df['b'].astype(str)
这里concat列的取值是['413', '413', '56'],其中'413'分组的col值是[1,2],集合大小为2,符合条件;'56'分组的col值是[3],集合大小为1,不符合。
- 方法一:先获取有效分组再筛选
# 计算每个分组的col集合长度,筛选出符合条件的分组键 valid_concats = df.groupby('concat')['col'].apply(lambda x: len(set(x)) > 1) # 提取符合条件的分组名称 valid_concats = valid_concats[valid_concats].index.tolist() # 筛选原DataFrame中属于有效分组的行 filtered_df = df[df['concat'].isin(valid_concats)]
运行后filtered_df会包含concat为'413'的两行数据。
- 方法二:用transform直接标记并筛选(更简洁)
transform可以将分组计算的结果广播到每一行,这样我们可以直接给原DataFrame添加一个标记列,再筛选:
# 给每行标记所在分组是否符合条件 df['group_valid'] = df.groupby('concat')['col'].transform(lambda x: len(set(x)) > 1) # 筛选符合条件的行 filtered_df = df[df['group_valid']]
为什么你的原代码报错?
你之前写的lambda x: set(x) if len(set(x)) > 1缺少了else分支,apply要求每个分组都必须返回一个值,当分组不满足条件时,这个lambda没有返回内容,Python就会抛出错误。而且你的目标是筛选行,不是生成字典,所以这种写法本身也不符合需求~
内容的提问来源于stack exchange,提问作者daiyue
相关产品推荐
相关产品推荐

