
本文介绍如何在 pandas 中处理重命名后出现的重复列名(如多个列被重命名为同一名称),并将其对应行值聚合为列表,避免数据丢失,同时保持原始行结构。
本文介绍如何在 pandas 中处理重命名后出现的重复列名(如多个列被重命名为同一名称),并将其对应行值聚合为列表,避免数据丢失,同时保持原始行结构。
当使用 df.rename(columns=names) 将多个原始列映射到相同列名(如 "a_1", "a_2", "a_3" 全部重命名为 "a")时,Pandas 会保留重复列名,形成具有非唯一列索引的 DataFrame。此时直接按列名访问(如 df2['a'])仅返回第一个 "a" 列,其余被隐式忽略——这正是我们需要聚合的根本原因。
正确解法是利用 列名作为分组依据,对每组同名列执行行内聚合。由于 groupby 默认按行(axis=0)操作,而我们要对“相同列名下的多列”进行横向聚合(即每行中所有名为 'a' 的列值合并为一个列表),最简洁高效的方式是:
- 转置 DataFrame:使原列变为行索引,原行变为列,从而将重复列名暴露为索引层级;
- 按索引层级分组:使用 groupby(level=0) 按第一级索引(即原列名)分组;
- 逐组聚合:对每组(如所有 'a' 列)应用自定义函数,过滤空字符串(x != ''),再转为列表;
- 转置回原结构:恢复行列方向,得到目标格式。
result = df2.T.groupby(level=0).agg(lambda x: x[x != ''].tolist()).T
✅ 输出结果:
a b c 0 [x] [] [z] 1 [x, y] [] [z]
⚠️ 注意事项:
- 该方法依赖 df2.columns.is_unique == False,即必须存在重复列名;若列名已去重,需先手动构造重复列(如 df2 = df2.rename(columns=names) 后不自动去重);
- 空值处理:示例中用 x != '' 过滤空字符串;如需处理 NaN,应改用 x.notna() 或 x.astype(bool) 配合 x.dropna();
- 性能提示:对大型 DataFrame,T.groupby(...).agg(...).T 是向量化操作,远优于 apply + 循环,推荐优先使用。
总结:Pandas 不支持原生“多列同名自动聚合”,但通过转置→按名分组→聚合→转回三步,可优雅、高效地实现按列名合并行值为列表的目标,是处理此类重命名聚合问题的标准范式。

















