DataFrame长转宽循环操作效率低下,寻求高效优化方案
优化DataFrame嵌套循环的高效解决方案
问题背景
需要将包含session_id、question、correct字段的长格式DataFrame df_labels转换为宽格式(每个question对应q_1到q_18列),并合并到包含全部session的df_sessions中。原嵌套循环代码逐行逐列赋值,单次操作耗时20分钟,效率极低。
优化方案
利用Pandas内置的矢量化操作替代循环,这是提升效率的核心。具体步骤如下:
1. 将长格式数据转为宽格式
使用pivot方法直接将question列转为列名,同时映射correct的值:
# 转换df_labels为宽格式 df_wide = df_labels.pivot( index='session_id', columns='question', values='correct' ).rename(columns=lambda col: f'q_{col}').reset_index()
- 如果存在同一
session_id+question的重复记录,改用pivot_table并指定聚合函数(比如取第一条记录、均值等):
df_wide = df_labels.pivot_table( index='session_id', columns='question', values='correct', aggfunc='first' # 根据需求可替换为'mean'/'max'等 ).rename(columns=lambda col: f'q_{col}').reset_index()
2. 合并到df_sessions
用merge方法将宽格式数据与df_sessions关联,保留所有session记录:
# 左连接合并,确保df_sessions的所有session都被保留 df_sessions = df_sessions.merge(df_wide, on='session_id', how='left')
原代码低效原因
原嵌套循环存在两个致命问题:
- 逐行逐列的循环操作完全没有利用Pandas的矢量化优势,每次循环都生成临时布尔索引对象,耗时极长;
- 使用链式索引(如
df_sessions[f'q_{i}'][df_sessions['session_id'] == session])可能触发SettingWithCopyWarning,同时底层是多次切片赋值,进一步拖慢速度。
效果对比
优化后的代码基于Pandas底层C实现的矢量化操作,原本20分钟的任务可在数秒内完成,同时代码更简洁、易维护。
内容的提问来源于stack exchange,提问作者user21082212
相关产品推荐
相关产品推荐

