拆分DataFrame为多列:代码缺失列问题排查与优化方案
问题描述
我的数据集结构类似下图(行数更多):
目标是得到如下结构:
我尝试的代码如下:
# Identify names that are in the dataset names = df['name'].unique().tolist() # Define dataframe with first name df1 = pd.DataFrame() df1 = df[(df == names[0]).any(axis=1)] df1 = df1.drop(['name'], axis=1) df1 = df1.rename({'color':'color_'+str(names[0]), 'number':'number_'+str(names[0])}, axis=1) # Make dataframes with other names and their corresponding color and number, add them to df1 df_merged = pd.DataFrame() for i in range(1, len(names)): df2 = pd.DataFrame() df2 = df[(df == names[i]).any(axis=1)] df2 = df2.drop(['name'], axis=1) df2 = df2.rename({'color':'color_'+str(names[i]), 'number':'number_'+str(names[i])}, axis=1) df_merged = df1.join(df2, lsuffix="_left", rsuffix="_right", how='left')
最终得到的df_merged结果如下:
可见color_Donald和number_Donald列缺失,循环似乎跳过或覆盖了Donald相关内容,求问原因及代码优化方法。
问题原因与优化方案
原因分析
- 循环覆盖问题:你每次循环都用初始的
df1和当前df2做join,然后把结果赋值给df_merged,这导致只有最后一次循环的结果会保留,之前的列全被覆盖。比如如果names是['Mickey', 'Donald', 'Goofy'],循环到Goofy时,df_merged就变成了df1+Goofy的列,Donald的列自然丢失。 - 筛选逻辑隐患:用
(df == names[i]).any(axis=1)筛选行,可能会误匹配到其他列(比如color/number)值和name相同的行,正确的筛选应该直接指定name列:df[df['name'] == names[i]]。
优化代码
方法一:用pivot一步到位(推荐)
pandas的pivot是处理这类宽表转换的标准方法,代码简洁高效:
# 给每个人的行添加序号,确保行对应(假设每个人的行数一致) df['row_id'] = df.groupby('name').cumcount() # 执行透视转换 result = df.pivot(index='row_id', columns='name', values=['color', 'number']) # 合并多层列名为目标格式 result.columns = [f'{col[0]}_{col[1]}' for col in result.columns] # 可选:移除row_id索引 result = result.reset_index(drop=True)
方法二:修复循环逻辑
如果一定要用循环,需要每次把新列合并到上一次的结果中,而不是每次都用初始的df1:
names = df['name'].unique().tolist() # 初始化结果为第一个name的数据 result = df[df['name'] == names[0]].drop('name', axis=1) result = result.rename(columns={'color': f'color_{names[0]}', 'number': f'number_{names[0]}'}) # 循环合并剩余name的数据 for name in names[1:]: temp_df = df[df['name'] == name].drop('name', axis=1) temp_df = temp_df.rename(columns={'color': f'color_{name}', 'number': f'number_{name}'}) # 合并到结果中,保证行索引对应 result = result.join(temp_df, how='left')
两种方法都能得到目标结构,优先用pivot方法,性能和可读性都更好。
内容的提问来源于stack exchange,提问作者newcomer
相关产品推荐
相关产品推荐

