
本文详解如何在 Pandas 中对多列(如 State 和 Make)进行分组,同时对指定数值列(如 Electric Range、Model Year)执行不同聚合操作,并原生、高效地添加每组记录数(count)列,全程不依赖 apply,完全基于 agg + NamedAgg。
本文详解如何在 pandas 中对多列(如 state 和 make)进行分组,同时对指定数值列(如 electric range、model year)执行不同聚合操作,并原生、高效地添加每组记录数(count)列,全程不依赖 apply,完全基于 agg + namedagg。
在使用 pandas.DataFrame.groupby() 进行多维度分析时,常需对不同列应用差异化聚合函数(例如:对 Electric Range 求均值、对 Model Year 取最小值),同时还希望直接获取每组的样本数量用于后续筛选或归一化计算。关键在于:count 必须作为独立聚合项与其它统计量并列输出,且不能破坏向量化性能。
正确做法是利用 pd.NamedAgg 在 .agg() 中显式声明多个聚合项,其中 count 可作用于任意非空列(推荐选择逻辑上必非空的列,如已过滤后的 Model Year 或分组键之一)。注意:"count" 是 Pandas 内置聚合函数,自动忽略 NaN,无需额外处理。
以下为完整可运行示例(基于问题中的数据结构和过滤逻辑):
import pandas as pd
# 假设 data 已加载为 DataFrame
filt = (data["Model Year"] >= 2018) & \
(data["Electric Vehicle Type"] == "Battery Electric Vehicle (BEV)")
result = (
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="Model Year", aggfunc="count") # ✅ 关键:添加 count 列
)
)
# 查看结果
print(result.head())输出示例:
State Make avg_electric_range oldest_model_year count 0 WA TESLA 217.666667 2018 12 1 WA NISSAN 84.000000 2018 5 2 WA TOYOTA 103.000000 2014 1 # 注意:此行不会出现,因 filt 已限定 Model Year >= 2018
✅ 注意事项与最佳实践:
-
避免使用
"size":"size"返回包括 NaN 的行数,而"count"自动排除 NaN,语义更准确;若需严格计数(含缺失值),才考虑size。 -
列选择建议:优先选用确定非空的列(如已通过布尔索引过滤的
Model Year),避免因目标列含 NaN 导致 count 偏低。 -
性能保障:所有聚合均在底层 Cython 实现,
NamedAgg不引入 Python 循环,比apply(lambda x: ...)快 5–10 倍以上。 -
扩展性提示:可继续追加任意数量
pd.NamedAgg,例如添加max_range=pd.NamedAgg("Electric Range", "max")或n_unique_models=pd.NamedAgg("Model", "nunique")。
最终生成的 result DataFrame 同时具备统计指标与频次信息,可直接用于下游分析,例如筛选 count >= 10 的主流厂商组合,或计算各厂商平均续航的加权均值。

















