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

为何按列(axis=1)使用pandas groupby会失效报错?

pandas列分组聚合报错分析与解决

原始数据与期望结果

原始DataFrame

import pandas as pd
df = pd.DataFrame({'item': [1, 2, 3, 4],
 'foo_x': ['A', 'D', 'H', 'L'],
 'foo_y': ['B', 'E', 'I', 'M'],
 'bar_x': ['C', 'F', 'J', 'N'],
 'bar_y': ['D', 'G', 'K', 'O']})

对应的表格:

itemfoo_xfoo_ybar_xbar_y
1ABCD
2DEFG
3HIJK
4LMNO

期望聚合结果

itemxy
1[A, C][B, D]
2[D, F][E, G]
3[H, J][I, K]
4[L, N][M, O]

报错代码与错误信息

报错代码

df_output = (
    df.rename(lambda x: x.split("_")[-1], axis=1)
        .groupby(level=0, axis=1).agg(list)
)

错误信息

ValueError: Length of values (2) does not match length of index (4)

报错原因解释

核心问题在于groupby(axis=1)时agg(list)的行为和你预期的完全相反:

  1. 第一步rename后,列名变为item, x, y, x, y,groupby(axis=1)按列名分成三组:item(1列)、x(2列)、y(2列)。
  2. pandas中agg(func)的默认逻辑是沿分组的反方向聚合:
    • 当axis=0(行分组)时,聚合沿列方向,符合常规直觉;
    • 当axis=1(列分组)时,聚合沿列方向(而非行方向):对于x组的2个列,agg(list)会把这2个列(每个是长度为4的Series)打包成一个长度为2的列表;而item组只有1个列,聚合结果长度为1。
  3. 合并结果时,x/y组的结果长度(2)与DataFrame索引长度(4)不匹配,因此抛出错误。

你预期的是按行聚合:对每一行,把同组的列值合并为列表,这和agg(list)的默认行为完全不同。

正确实现方式

方法1:分组后逐行apply处理

df_output = (
    df.rename(lambda x: x.split("_")[-1], axis=1)
      .groupby(level=0, axis=1)
      .apply(lambda g: g.apply(list, axis=1))
)

方法2:更高效的直接分组聚合

无需提前rename,直接提取列名后缀分组,再按行合并为列表:

# 提取每个列名的后缀(item列后缀为自身)
groups = df.columns.str.split("_").str[-1]
# 按后缀分组,对每组列按行合并成列表
df_output = df.groupby(groups, axis=1).agg(lambda x: x.values.tolist())
# 调整列顺序为item、x、y(可选)
df_output = df_output[['item', 'x', 'y']]

两种方法都能得到你期望的结果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 12:31:04