
本文详解如何在 Pandas 中对多列进行分组(groupby),对指定数值列执行不同聚合(如均值、最小值),并原生、高效地添加分组计数列(count),全程不依赖 apply,保持向量化性能。
本文详解如何在 pandas 中对多列进行分组(groupby),对指定数值列执行不同聚合(如均值、最小值),并**原生、高效地添加分组计数列(count)**,全程不依赖 `apply`,保持向量化性能。
在使用 pandas.DataFrame.groupby() 进行多列分组与聚合时,常需同时计算统计指标(如均值、最小值)和每组样本数量。关键在于:count 是一种标准聚合函数,可与其他 NamedAgg 并列定义,无需额外 apply 或 size() 等易混淆操作。
以您的数据为例——筛选 2018 年及以后的纯电动车(BEV),按 State 和 Make 分组,需计算:
- 平均续航(
Electric Range的均值) - 最早车型年份(
Model Year的最小值) - 每组车辆数量(即
count)
正确写法如下(推荐使用 pd.NamedAgg 显式声明,语义清晰且兼容性好):
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") # ✅ 安全:Model Year 为非空 int64,无 NaN 风险
))
? 为什么选
Model Year做 count?
因其类型为int64且筛选后无缺失值(filt已确保Model Year >= 2018),故count统计的是该组有效记录数(等价于size())。若某列含NaN,count会自动忽略缺失值,而size()返回总行数(含 NaN),二者语义不同,需按需选择。
你也可以用任意非空列(如 "VIN (1-10)" 或 "DOL Vehicle ID")替代 Model Year,只要确保该列在筛选后无缺失即可:
# 等效写法(使用 VIN 列计数) count=pd.NamedAgg(column="VIN (1-10)", aggfunc="count")
✅ 输出结果将包含 State、Make、avg_electric_range、oldest_model_year 和新增的 count 列,结构规整,可直接用于后续过滤(例如:result[result['count'] >= 10] 筛出高频品牌-州组合)。
⚠️ 注意事项:
- 避免使用
.size()方法返回Series后再reset_index(name='count'),虽可行但冗余,破坏链式表达; - 不要误用
agg('count')(未指定 column)——这会尝试对所有列计数,引发KeyError; - 若需严格计数(含 NaN 行),应改用
size(作为聚合函数需配合lambda x: len(x)或通过groupby(...).size().reset_index(name='count')),但本场景中count更符合“有效样本数”的业务含义。
综上,在 agg() 中并列添加 pd.NamedAgg(column=..., aggfunc='count') 是最简洁、高效、可读性强的标准解法,完全遵循 Pandas 最佳实践,兼顾性能与可维护性。










