如何将Pandas DataFrame中同名列的数值合并为列表?
解决Pandas同名列合并为列表的问题
问题场景
先创建列名唯一的DataFrame,通过rename将多列重命名为相同名称:
import pandas as pd df = pd.DataFrame({ "a_1": ["x", "x"], "a_2": ["", ""], "b_1": ["", ""], "a_3": ["", "y"], "c_1": ["z", "z"], }) names = { "a_1": "a", "a_2": "a", "a_3": "a", "b_1": "b", "c_1": "c", } df2 = df.rename(columns=names)
得到包含同名列的df2后,希望将同名列的每行数值合并为列表,期望输出:
out = pd.DataFrame({ "a": [["x"], ["x", "y"]], "b": [[""], [""]], "c": [["z"], ["z"]], }) a b c 0 [x] [] [z] 1 [x, y] [] [z]
报错原因分析
尝试用循环+apply实现时出现报错:
for c in ['a', 'b', 'c']: df2[c] = df2[c].apply(lambda x: x.tolist() if x.any() else [], axis=1)
报错信息:
TypeError: <lambda>() got an unexpected keyword argument 'axis'
问题出在:当df2存在同名列时,df2[c]返回的是多列的DataFrame,你误将axis=1参数传给了lambda函数(实际axis是apply方法的参数,不是lambda的参数)。另外,即使参数位置正确,循环后会保留重复列名,还需要额外处理。
正确解决方案
方法一:按列名分组(推荐)
直接用groupby(axis=1)按列名分组,将每组的行值转为列表,一步到位:
# 按列名分组,将每组的每行数据转为列表 out = df2.groupby(df2.columns, axis=1).apply(lambda x: x.values.tolist()) # 或者更直观的写法: out = df2.groupby(axis=1, level=0).apply(lambda group: group.apply(list, axis=1)) print(out)
输出结果完全符合预期:
a b c 0 [x] [""] ["z"] 1 [x, y] [""] ["z"]
方法二:修正原有循环代码
如果坚持用循环,需调整apply的写法,并最后去重列名:
for c in ['a', 'b', 'c']: # df2[c]是DataFrame,apply按行操作,x为每行的Series df2[c] = df2[c].apply(lambda x: x.tolist(), axis=1) # 移除重复的列名,只保留每个列名的第一列 out = df2.loc[:, ~df2.columns.duplicated()]
说明
- 方法一无需循环,利用Pandas的分组机制高效处理,代码更简洁易维护。
- 方法二适合理解分步逻辑,但需要额外处理重复列名的问题。
内容的提问来源于stack exchange,提问作者aeiou
相关产品推荐
相关产品推荐

