
本文介绍如何使用 pandas 的 melt() 方法,将 Excel 中以人员为列、日期为行的宽格式考勤数据(如 Bob/Joe/Jane 各列为标题),高效重塑为“Date–Name–On/Off”三列结构的长格式表格,适用于后续分析或可视化。
本文介绍如何使用 pandas 的 `melt()` 方法,将 excel 中以人员为列、日期为行的宽格式考勤数据(如 bob/joe/jane 各列为标题),高效重塑为“date–name–on/off”三列结构的长格式表格,适用于后续分析或可视化。
在数据分析中,原始数据常以宽格式(wide format)存储——即每个实体(如员工)占据一列,时间维度(如日期)作为行索引。但多数统计建模、时间序列分析或可视化库(如 seaborn、plotly)更倾向接收长格式(long format):每行代表一个观测单元,关键变量拆分为独立字段。本文所涉场景正属典型:原始 Excel 表含列 "Date", "Bob", "Joe", "Jane",需转换为 "Date", "Name", "On/Off" 三列结构,其中 "Name" 来源于原列名,"On/Off" 来源于对应单元格值。
实现该转换最简洁、可靠的方式是使用 pandas 的 pd.melt() 函数。其核心逻辑是:指定一个或多个“标识变量”(id_vars)保持不变(此处为 "Date"),其余所有列自动被“融化”(melting)为两列——一列存原列名(默认名为 "variable"),一列存对应值(默认名为 "value")。随后通过 .rename() 映射列名即可完成目标结构。
以下是完整可执行代码示例:
import pandas as pd
# 1. 读取 Excel 数据(请替换为实际文件路径)
df = pd.read_excel("schedule.xlsx")
# 2. 执行重塑:以 Date 为标识列,其余列为待熔化列
df_long = pd.melt(
df,
id_vars="Date", # 保持不变的列(日期列)
var_name="Name", # 原列名将存入此列(替代默认 'variable')
value_name="On/Off" # 原单元格值将存入此列(替代默认 'value')
)
# 3. (可选)按 Date 和 Name 排序,使结果更易读
df_long = df_long.sort_values(["Date", "Name"]).reset_index(drop=True)
# 4. 导出为 CSV(不保存 pandas 默认索引)
df_long.to_csv("schedule_long.csv", index=False)⚠️ 注意事项:
- 确保 Excel 文件中
"Date"列名拼写完全一致(区分大小写),否则id_vars="Date"将报错; - 若 Excel 存在空行或合并单元格,
read_excel()可能解析异常,建议预先在 Excel 中清理数据; -
melt()不会修改原 DataFrame,返回新对象,因此务必赋值给变量(如df_long); - 如需进一步处理(例如将
"On/Off"转为布尔型),可追加:df_long["On/Off"] = df_long["On/Off"].astype(bool); - 替代方案如
df.stack().reset_index()也可实现类似效果,但melt()语义更清晰、参数更直观,是官方推荐的长格式转换首选方法。
经上述步骤,原始 3 行 × 4 列的宽表将精确转换为 9 行 × 3 列的长表,严格满足 "Date", "Name", "On/Off" 的结构要求,为后续按人聚合、按日统计或构建交互式排班看板奠定规范数据基础。

















