Pandas多列分组聚合后添加分组计数列的实现(排除apply方法)
Pandas多列分组聚合后添加分组计数列的实现(排除apply方法)
看起来你已经搞定了分组聚合的核心逻辑,现在就差给结果加一个分组计数列,还要求不能用apply,完全用Pandas原生的方法对吧?这事儿其实超简单,直接在你现有的agg聚合操作里加一项就行,根本不用绕弯子。
具体修改方案
你只需要在agg的参数里新增一个Count列的聚合规则,用size作为聚合函数(选一个不会有缺失值的列,比如唯一标识的VIN列),就能直接得到每个State-Make分组的总条数。
修改后的完整代码如下:
import pandas as pd # 保留你原有的过滤条件 filt = (data["Model Year"] >= 2018) & (data["Electric Vehicle Type"] == "Battery Electric Vehicle (BEV)") # 在agg中新增Count列的聚合 data_agg = data[filt].groupby(["State", "Make"], sort=False, observed=True, as_index=False).agg( avg_electric_range=pd.NamedAgg(column="Electric Range", aggfunc="mean"), oldest_model_year=pd.NamedAgg(column="Model Year", aggfunc="min"), Count=pd.NamedAgg(column="VIN (1-10)", aggfunc="size") # size统计分组内的总行数 )
为什么这么做?
- 用
size而不是count:size会直接统计分组的总行数,不管列有没有空值;而count会忽略空值,选VIN这种唯一且无缺失的列配合size,结果最准确。 - 完全在聚合链内完成:没有用到
apply,纯Pandas原生操作,效率和可读性都拉满。
更简洁的写法(可选)
如果你觉得pd.NamedAgg有点繁琐,还可以用更简洁的元组写法,效果完全一样:
data_agg = data[filt].groupby(["State", "Make"], sort=False, observed=True, as_index=False).agg( avg_electric_range=("Electric Range", "mean"), oldest_model_year=("Model Year", "min"), Count=("VIN (1-10)", "size") )
后续过滤使用
得到带Count列的结果后,你就可以直接用这个列做进一步过滤了,比如只保留分组数量大于50的结果:
# 示例:过滤出分组数量超过50的记录 data_filtered = data_agg[data_agg["Count"] > 50]
修改后的结果会是这样的:
State Make avg_electric_range oldest_model_year Count 0 WA TESLA 52.143448 2018 1245 1 WA NISSAN 60.051874 2018 321 <snip>
备注:内容来源于stack exchange,提问作者khteh
相关产品推荐
相关产品推荐

