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

使用pandas agg添加mode函数触发聚合转换组合错误的解决咨询

Pandas中使用agg同时聚合mode与其他函数的问题解决

问题重现

先构造测试DataFrame:

import pandas as pd
import numpy as np

df_test = pd.DataFrame(np.array([[1,1,2,2,2],[3,3,4,4,5]]).T,columns=['A','B'])

输出:

A   B
0   1   3
1   1   3
2   2   4
3   2   4
4   2   5

使用agg聚合min、max、mean、median时一切正常:

df_test.agg(['min','max','mean','median'])

输出:

A    B
min     1.0  3.0
max     2.0  5.0
mean    1.6  3.8
median  2.0  4.0

但添加mode到聚合列表后直接报错:

df_test.agg(['min','max','mean','median','mode'])

错误信息:

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
/usr/local/lib/python3.7/dist-packages/pandas/core/apply.py in agg_list_like(self)
    381         try:
--> 382             concatenated = concat(results, keys=keys, axis=1, sort=False)
    383         except TypeError as err:

11 frames
TypeError: cannot concatenate object of type '<class 'numpy.int64'>'; only Series and DataFrame objs are valid

The above exception was the direct cause of the following exception:

ValueError                                Traceback (most recent call last)
/usr/local/lib/python3.7/dist-packages/pandas/core/apply.py in agg_list_like(self)
    390                 raise ValueError(
    391                     "cannot combine transform and aggregation operations"
--> 392                 ) from err
    393             return result
    394         else:

ValueError: cannot combine transform and aggregation operations

即使改用每列只有一个众数的DataFrame,错误依然存在:

df_test = pd.DataFrame(np.array([[1,1,2,2,2],[3,3,3,4,4]]).T,columns=['A','B'])
df_test.agg(['min','max','mean','median','mode'])

原因分析

mode()方法返回的是Series(单列聚合时)或DataFrame(多列聚合时),而min、max等其他聚合函数返回的是单个标量值。当agg尝试将这些结果拼接成最终输出时,不同类型的返回值(标量 vs Series/DataFrame)会触发拼接错误——pandas无法将标量和Series/DataFrame直接合并。

哪怕单列只有一个众数,mode()返回的也是长度为1的Series,而非标量,因此依然会和其他标量结果冲突。

解决方案

方法1:用Lambda函数提取众数的第一个值

通过lambda函数对每个列的mode结果取第一个元素,确保返回标量:

# 直接聚合,最后一行默认名为<lambda>
df_test.agg(['min','max','mean','median', lambda x: x.mode().iloc[0]])

# 重命名行,让结果更清晰
result = df_test.agg(['min','max','mean','median', lambda x: x.mode().iloc[0]])
result.rename(index={result.index[-1]: 'mode'}, inplace=True)
print(result)

输出:

A    B
min     1.0  3.0
max     2.0  4.0
mean    1.6  3.4
median  2.0  3.0
mode    2.0  3.0

方法2:自定义聚合函数

封装一个返回标量的众数函数,代码可读性更好:

def get_mode(x):
    # 返回众数的第一个值,确保是标量
    return x.mode().iloc[0]

# 使用自定义函数聚合
result = df_test.agg(['min','max','mean','median', get_mode])
# 重命名行
result.rename(index={result.index[-1]: 'mode'}, inplace=True)
print(result)

方法3:用字典形式指定聚合函数

如果需要为不同列配置不同的聚合规则,或者更明确地定义函数,用字典形式:

df_test.agg({
    'A': ['min', 'max', 'mean', 'median', get_mode],
    'B': ['min', 'max', 'mean', 'median', get_mode]
})

关于mode()[0]尝试失败的说明

之前直接写mode()[0]报错是因为没有正确引用pandas的mode方法——这里的mode必须是针对每个列(Series对象)的方法,而非全局函数。正确的写法是在lambda或自定义函数中对输入的Series调用x.mode().iloc[0],而不是直接调用未定义的mode()。

内容的提问来源于stack exchange,提问作者Musa H. Asyali

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 10:50:46