pandas中如何水平、垂直合并多个pivot table得到目标输出
问卷数据长转宽实现方案
你提出的逐题生成透视表再横向拼接的思路可行,但不是最优方案:当题目数量多、样本量大时,重复透视+逐表拼接不仅运行效率低,还很容易因为索引不统一出现行错位、列名重复的问题。
更高效的实现逻辑
不需要拆分题目逐个处理,用一次透视操作就能直接输出目标格式的宽表,核心步骤如下:
- 先确认原始长表的核心字段:从原始数据样例来看,属于典型的问卷明细存储结构,必备字段包括受访者唯一ID、题号(Q1/Q2…)、选项内容、回答标记/取值四类
- 直接调用透视方法,以受访者ID为行索引,以「题号+选项」的组合为列维度,填充值取回答标记,一次完成全量题目的宽表转换
- 最后调整列名格式、按题号排序列顺序,保证同一个题目下的所有选项列连续排列即可
可直接复用的参考代码
import pandas as pd # 读取原始数据,替换为你自己的文件读取逻辑 raw_df = pd.read_excel("raw_survey_data.xlsx") # 一次性透视生成宽表,注意替换参数为你实际表中的字段名 # index: 传入能唯一标记单个受访者的字段,比如resp_id、user_id # columns: 传入要展开为列的两个维度:题号列、选项列 # values: 传入单元格填充的取值,比如多选的选中标记、打分题的分值 # fill_value: 未选中/无回答的单元格填充值,一般多选填0,打分题按需填空值 wide_df = pd.pivot_table( raw_df, index="resp_id", columns=["question_id", "option_content"], values="answer_mark", aggfunc="max", fill_value=0 ).reset_index() # 扁平化多级列名,拼接成「题号_选项」的常用格式 wide_df.columns = [ f"{level1}_{level2}" if level2 else level1 for level1, level2 in wide_df.columns ] # 按题号排序列,保证同一道题的选项列连续排列 sorted_columns = ["resp_id"] + sorted( [col for col in wide_df.columns if col.startswith("Q")], key=lambda x: int(x.split("_")[0][1:]) ) final_result = wide_df[sorted_columns]
如果坚持用逐题拼接思路的避坑提示
如果你的数据存在特殊结构、必须拆分题目逐个处理,注意两个核心问题避免出错:
- 每道题生成透视表时,必须统一使用受访者ID作为索引,不要用默认的整数索引,否则后续横向拼接时会出现严重的行错位
- 每道题的透视结果生成后立刻修改列名,保证列名全局唯一,不要等全部拼接完再统一处理,否则很容易出现同名列覆盖的问题
内容的提问来源于stack exchange,提问作者Ashna
相关产品推荐
相关产品推荐

