如何用Pandas调整透视表参数实现指定Dataframe格式转换
问题描述
现有如下结构的数据集:
| 用户 | 槽位 | 问题 | 答案 |
|---|---|---|---|
| 1 | 1 | Q1 | A1 |
| 1 | 2 | Q2 | A2 |
| 1 | 3 | Q3 | A3 |
| 999 | 1 | Q1 | A1 |
| 999 | 2 | Q2 | A2 |
| 999 | 3 | Q3 | A3 |
希望将其转换为以下格式的表格,要求列按「问题N、答案N」的顺序排列:
| 用户 | 问题1 | 答案1 | 问题2 | 答案2 |
|---|---|---|---|---|
| 1 | Q1 | A1 | Q2 | A2 |
| 999 | Q1 | A1 | Q2 | A2 |
目前通过循环逐个处理用户子DataFrame再合并的方式实现,代码如下:
df_merged = pd.DataFrame() for item in users: sub_df = df.loc[df['username'] == item] sub_df = sub_df.pivot(index='username', columns='slot', values=['questionsummary', 'responsesummary']) df_merged = pd.concat([df_merged, sub_df])
但得到的列顺序为「用户、问题1、问题2、答案1、答案2」,不符合需求,需调整列排列顺序。
解决方案
方法1:基于现有代码调整列顺序
透视后会生成多层列索引,我们可以重新排列列的顺序,让「问题N」与「答案N」成对出现,再合并列索引为单层:
df_merged = pd.DataFrame() for item in users: sub_df = df.loc[df['username'] == item] sub_df = sub_df.pivot(index='username', columns='slot', values=['questionsummary', 'responsesummary']) # 按槽位分组,每组内先问题后答案 new_cols = [] for slot in sub_df.columns.get_level_values(1).unique(): new_cols.append(('questionsummary', slot)) new_cols.append(('responsesummary', slot)) sub_df = sub_df[new_cols] # 将多层列索引转为单层,命名为"问题N""答案N" sub_df.columns = [f'问题{slot}' if col == 'questionsummary' else f'答案{slot}' for col, slot in sub_df.columns] df_merged = pd.concat([df_merged, sub_df])
方法2:直接透视后批量调整(更高效)
无需循环处理单个用户,直接对整个DataFrame透视后一次性调整列顺序:
# 对全量数据执行透视 pivoted_df = df.pivot(index='用户', columns='槽位', values=['问题', '答案']) # 生成目标列顺序:遍历槽位,每组先问题后答案 target_cols = [] for slot in pivoted_df.columns.get_level_values(1).unique(): target_cols.append(('问题', slot)) target_cols.append(('答案', slot)) # 重新排序列 pivoted_df = pivoted_df[target_cols] # 合并多层列索引为单层 pivoted_df.columns = [f'{col}{slot}' for col, slot in pivoted_df.columns] # 可选:将"用户"从索引转为普通列 pivoted_df = pivoted_df.reset_index()
以上两种方法都能得到「用户、问题1、答案1、问题2、答案2...」的列顺序,满足需求。
内容的提问来源于stack exchange,提问作者Jerry Waa
相关产品推荐
相关产品推荐

