You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

pandas如何堆叠多列数据并按原始来源列生成对应匹配字段

问题原因

原代码存在两个核心错误:

  1. 实现逻辑偏差:np.select仅能在原宽表的单行维度赋值,而需求本质是宽表转长表——每个TestID对应3条不同科目的记录,宽表单行仅能存储1个TestDate值,无法承载三个科目的不同考试日期。
  2. 判断条件失效:数据集中ELA/Math/Science列存储的是W/P/NI/A类成绩值,所有行的ELA列均不等于字符串'[]',np.select按顺序优先命中第一个满足的条件,因此所有行都被赋值为第一个匹配值April 1。
可行解决方案

pandas内置的melt方法专门用于这类列堆叠的宽长表转换场景,无需手动编写多条件判断,实现步骤:

  • 调用melt保留无需拆分的TestID列,将三个科目列堆叠为两列:原科目列名存入TestName字段,对应成绩值存入Score字段
  • 构建科目与考试日期的映射字典,通过字段映射快速生成TestDate列
  • 调整列顺序、按需排序,匹配预期输出格式

完整实现代码:

import pandas as pd

# 完成成绩列堆叠,宽表转长表
df_long = df.melt(
    id_vars="TestID",
    value_vars=["ELA", "Math", "Science"],
    var_name="TestName",
    value_name="Score"
)

# 批量匹配对应考试日期
date_map = {"ELA": "April 1", "Math": "May 1", "Science": "June 1"}
df_long["TestDate"] = df_long["TestName"].map(date_map)

# 按TestID、科目排序,调整列顺序
df_long = df_long.sort_values(
    by=["TestID", "TestName"], 
    ignore_index=True
)[["TestID", "TestName", "TestDate", "Score"]]

运行后输出结果与预期完全一致,前6行示例:

TestID TestName TestDate Score
0  1005327      ELA  April 1     P
1  1005327     Math    May 1     P
2  1005327  Science  June 1     P
3  1020285      ELA  April 1    NI
4  1020285     Math    May 1     P
5  1020285  Science  June 1     W

内容的提问来源于stack exchange,提问作者Steve

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 10:51:21