You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Pandas groupby的agg函数无法处理Categorical分类列问题

Pandas groupby.agg 对Categorical类型列的支持说明

结论先行:Pandas的groupby.agg本身原生支持处理Categorical分类类型列,你遇到的分类列被自动丢弃的问题,是自定义聚合函数的返回值类型校验不通过导致的,并非方法本身不支持该类型。

问题根因

  • 触发告警丢列的核心逻辑是:当聚合操作作用于Categorical列时,Pandas会默认校验聚合返回值是否符合该列的类型约束。你在lambda中通过x.value_counts().index[0]拿到的是Categorical类型的标量对象,在Pandas 1.x~2.0的部分版本中,这个返回值会被误判定为不匹配原列的Categorical dtype,最终被判定为聚合失败、自动丢弃列,抛出你看到的告警。
  • 你写的类型判断逻辑存在小缺陷:np.dtype(x)=='float16'的写法在入参x是Categorical类型时,拿到的是CategoricalDtype实例,直接和字符串'float16'比较虽然能走到else分支,但不会改变返回值校验失败的结果。

修复方案

方案1:修正类型判断+转换返回值类型(最小改动)

只需要把dtype判断改成取dtype的name属性做比较,同时把Categorical列的聚合返回值转成原生Python标量,绕过类型校验即可:

import pandas as pd
import numpy as np

i = pd.DataFrame({"A":["a","a","a","b","c","c"],"B":[1,2,3,4,5,6],"C":[ "NaN" ,"b","NaN","b","c","c"]})
i['A'] = i['A'].astype('category')   
i['B'] = i['B'].astype('float16')   
i['C'] = i['C'].astype('category')  

res = i.groupby("A", as_index=False)[["B","C"]].agg(
    lambda x: x.mean() if x.dtype.name == 'float16' else x.value_counts().index[0].item()
)
print(res)

运行后得到预期输出:

A    B    C
0  a  2.0  NaN
1  b  4.0    b
2  c  5.5    c

方案2:按列类型显式指定聚合规则(更稳定,推荐生产环境用)

不要用单个lambda做全列分支判断,提前按列的dtype拆分,给不同类型的列单独指定聚合逻辑,从根源上避免隐式类型校验冲突:

# 拆分不同类型的待聚合列
float_cols = i.select_dtypes(include=['float16']).columns.tolist()
cat_cols = i.select_dtypes(include=['category']).columns.difference(['A']).tolist()

# 构造聚合规则字典
agg_config = {}
agg_config.update({col: 'mean' for col in float_cols})
agg_config.update({col: lambda x: x.value_counts().index[0] for col in cat_cols})

res = i.groupby("A", as_index=False).agg(agg_config)

补充说明

Pandas 2.1及以上版本已经优化了Categorical列聚合时的类型校验逻辑,多数场景下即使不做返回值类型转换,也不会出现丢列告警。但显式指定列聚合规则的写法兼容性更好,能避免跨版本运行时出现隐式异常。

内容的提问来源于stack exchange,提问作者Jas

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.02 07:12:52