pandas DataFrame.agg方法异常探究:Lambda返回同Series但聚合结果不同?
agg 对返回Series的函数有不同的拼接逻辑 这个现象本质上是因为pandas的agg方法会根据你调用它的上下文(普通DataFrame还是分组后的GroupBy对象)、聚合轴(axis参数),甚至传入函数的方式(单个函数还是字典映射),采用完全不同的规则来拼接每个Lambda返回的Series,哪怕每个Lambda返回的Series内容、结构完全一致。
我用几个具体场景给你拆解:
1. 聚合轴(axis)不同导致的结果差异
假设我们有一个简单的DataFrame:
import pandas as pd df = pd.DataFrame({'a': [1,2,3], 'b': [4,5,6]})
我们定义一个返回固定Series的Lambda:
my_lambda = lambda x: pd.Series([x.min(), x.max()], index=['min_val', 'max_val'])
当用
axis=0(默认,按列聚合)调用agg时:result_axis0 = df.agg(my_lambda)结果是一个以原DataFrame列名为行索引,以Lambda返回Series的索引为列名的DataFrame:
min_val max_val a 1 3 b 4 6原因:
axis=0时,Lambda会被逐列执行(每个x是一列的Series),然后把每列的结果Series按行拼接,行标签就是原列名。当用
axis=1(按行聚合)调用agg时:result_axis1 = df.agg(my_lambda, axis=1)结果是一个以原DataFrame行索引为行索引,以Lambda返回Series的索引为列名的DataFrame:
min_val max_val 0 1 4 1 2 5 2 3 6原因:
axis=1时,Lambda会被逐行执行(每个x是一行的Series),然后把每行的结果Series按行拼接,行标签就是原行索引。
2. 普通DataFrame vs GroupBy对象的agg差异
还是用上面的DataFrame,我们先分组:
df['group'] = ['X', 'X', 'Y'] grouped_df = df.groupby('group')
同样用之前的my_lambda调用agg:
grouped_result = grouped_df.agg(my_lambda)
结果会是一个多级列索引的DataFrame:
a b min_val max_val min_val max_val group X 1 2 4 5 Y 3 3 6 6
而普通DataFrame的agg结果是单级列索引、原列名为行索引的结构。这是因为GroupBy的agg会将分组键作为行索引,同时把原列名和Lambda返回Series的索引组合成多级列索引,以此区分不同列的聚合结果;而普通DataFrame的agg则是把原列名直接作为行索引来展示每列的聚合结果。
3. 单个函数传入 vs 字典映射传入的差异
如果我们用字典指定仅对部分列应用Lambda:
dict_result = df.agg({'a': my_lambda})
结果只会包含指定列的聚合结果:
min_val max_val a 1 3
而直接传入单个函数会对所有列执行聚合,结果包含所有列的信息。
总结一下:Lambda返回的Series只是单个聚合单元的结果,agg会根据自身的运行上下文,选择不同的拼接规则来组合这些单元结果,最终呈现出不同的结构——这就是你看到“返回相同Series但聚合结果不同”的核心原因。
内容的提问来源于stack exchange,提问作者V. Ayrat

