为何Pandas的groupby命令会生成原DataFrame中不存在的courier_id?
Pandas Groupby出现原DataFrame不存在的分组键问题
问题重现
执行以下分组统计命令时,结果中出现了原DataFrame里不存在的courier_id,对应计数为0:
df.groupby('courier_id').type_of_vehicle.size()
示例输出中包含如01cef7ba-e32e-11ec-bb21-67c7079055d4这类不存在的ID,且:
- 执行
'01cef7ba-e32e-11ec-bb21-67c7079055d4' in df.courier_id.values返回False - 调用
df.groupby('courier_id').get_group('01cef7ba-e32e-11ec-bb21-67c7079055d4')触发KeyError - 遍历分组时会返回空DataFrame
- 仅保留
courier_id和type_of_vehicle两列切片后(new_df = df[['courier_id', 'type_of_vehicle']]),分组结果恢复正常
原因分析
核心原因是原DataFrame的courier_id列是分类(Categorical)数据类型。分类类型会预先存储一组固定的类别集合,即使某些类别在当前DataFrame的实际数据中没有出现,groupby默认会保留所有预设类别,因此会出现这些不存在的courier_id,计数为0。而切片操作会自动将分类类型转换为普通对象(object)类型,此时groupby仅统计实际存在的键。
验证方式:执行以下代码检查列类型:
print(df['courier_id'].dtype)
若输出为CategoricalDtype(...),即可确认是分类类型导致的问题。
解决方案
方案1:分组时指定observed=True
在groupby中添加observed=True参数,强制仅统计实际出现的类别:
df.groupby('courier_id', observed=True).type_of_vehicle.size()
方案2:转换为普通对象类型
将courier_id列从分类类型转为普通对象类型,之后再执行分组:
df['courier_id'] = df['courier_id'].astype(object) df.groupby('courier_id').type_of_vehicle.size()
方案3:读取数据时避免识别为分类
如果是从外部文件读取数据,可直接指定该列的类型为object,避免自动识别为分类:
# 以读取CSV为例 df = pd.read_csv('your_data.csv', dtype={'courier_id': object})
内容的提问来源于stack exchange,提问作者S. Hossein Motaharpour
相关产品推荐
相关产品推荐

