使用Pandas groupby对象过滤时遇TypeError:'function'对象不可迭代
Pandas filter方法报错TypeError的问题解决
问题重现
你执行了以下代码创建聚合后的DataFrame:
groupby=df.groupby('Product_1').mean().reset_index()
随后尝试用filter过滤:
groupby.filter(lambda x: x['s_qual'].mean() > 3)
收到错误:
--------------------------------------------------------------------------- TypeError Traceback (most recent call last) C:\Users\A~1\AppData\Local\Temp/ipykernel_48512/2738959142.py in <module> ----> 1 groupby.filter(lambda x: x['s_qual'].mean() > 3.) ~\anaconda3\lib\site-packages\pandas\core\generic.py in filter(self, items, like, regex, axis) 4980 if items is not None: 4981 name = self._get_axis_name(axis) -> 4982 return self.reindex(**{name: [r for r in items if r in labels]}) 4983 elif like: 4984 TypeError: 'function' object is not iterable
错误原因
核心问题是你搞混了两种完全不同的filter方法:
- 执行
df.groupby('Product_1').mean().reset_index()后,得到的是普通的DataFrame,不是Pandas的GroupBy对象。 - 两个
filter的功能完全不一样:- GroupBy的
filter是用来筛选分组的,接受函数判断每个分组是否符合条件; - DataFrame的
filter是用来按名称筛选行/列的,只支持列名列表、like匹配或regex匹配,根本不能传函数。
- GroupBy的
报错里的“不可迭代函数”,就是你传入的那个lambda函数。DataFrame的filter方法把你传的函数当成了要遍历的列名列表,但函数不是可迭代对象(没法用for循环遍历它的元素),所以抛出了这个错误。
解决方法
分两种场景处理:
场景1:先聚合,再过滤聚合结果
如果已经完成分组聚合,只想筛选聚合后的结果,直接用布尔索引即可:
# 先得到聚合后的DataFrame(建议换个变量名,避免和GroupBy对象混淆) agg_df = df.groupby('Product_1').mean().reset_index() # 直接筛选s_qual列值大于3的行 filtered_df = agg_df[agg_df['s_qual'] > 3]
场景2:先筛选符合条件的分组,再聚合
如果想先保留s_qual均值大于3的分组,再做聚合,就要保留GroupBy对象,不要提前执行mean()和reset_index():
# 先创建GroupBy对象,不提前聚合 grouped = df.groupby('Product_1') # 用GroupBy的filter筛选出符合条件的分组数据 filtered_groups = grouped.filter(lambda x: x['s_qual'].mean() > 3) # 对筛选后的分组数据做聚合 agg_filtered = filtered_groups.groupby('Product_1').mean().reset_index()
内容的提问来源于stack exchange,提问作者a.a
相关产品推荐
相关产品推荐

