
本文介绍如何使用 pandas 的 melt() 方法,将 Excel 中“日期-人员”宽格式考勤数据(如 Bob/Joe/Jane 各列为标题)高效转换为标准长格式,生成包含 Date、Name、On/Off 三列的规范化表格。
本文介绍如何使用 pandas 的 `melt()` 方法,将 excel 中“日期-人员”宽格式考勤数据(如 bob/joe/jane 各列为标题)高效转换为标准长格式,生成包含 date、name、on/off 三列的规范化表格。
在数据分析与报表处理中,原始数据常以宽格式(wide format)存储——即每个人员独占一列,日期作为行索引。但下游分析(如按人统计出勤率、时序建模或导入 BI 工具)通常要求长格式(long format),即每行代表一个“日期-人员-状态”的原子观测。这种结构转换称为数据重塑(reshaping),而 pandas.melt() 正是专为此类任务设计的核心方法。
以下为完整操作流程(基于 Python 3.x 和 pandas ≥ 2.0):
✅ 步骤 1:读取 Excel 数据
import pandas as pd
# 替换为你的实际文件路径
df = pd.read_excel("schedule.xlsx")
print(df.head())
假设原始数据如下: | Date | Bob | Joe | Jane | |----------|-----|-----|------| | 1/1/2025 | 0 | 0 | 0 | | 1/2/2025 | 1 | 1 | 1 | | 1/3/2025 | 1 | 1 | 1 |
✅ 步骤 2:执行熔解(melt)重塑
# 将 'Date' 列设为标识变量(保持不变),其余列转为行
df_long = pd.melt(
df,
id_vars="Date", # 不参与重塑的列(保留为基准维度)
var_name="Name", # 指定原列名(Bob/Joe/Jane)转为目标列名
value_name="On/Off" # 指定原单元格值转为目标列名
)
? 关键参数说明:
id_vars: 必须是字符串或列表,指定哪些列“不动”,作为分组依据;var_name: 新生成的列名,用于存放原列标题(即人员姓名);value_name: 新生成的列名,用于存放原单元格数值(即 0/1 出勤状态)。
执行后,df_long 即为期望的长格式结构:
| Date | Name | On/Off |
|----------|------|--------|
| 1/1/2025 | Bob | 0 |
| 1/2/2025 | Bob | 1 |
| 1/3/2025 | Bob | 1 |
| 1/1/2025 | Joe | 0 |
| ... | ... | ... |
✅ 步骤 3:导出结果(可选)
# 保存为 CSV(不写入 pandas 默认索引)
df_long.to_csv("schedule_long.csv", index=False)
# 或直接写回 Excel
df_long.to_excel("schedule_long.xlsx", index=False)
⚠️ 注意事项
-
日期类型处理:若
Date列被识别为字符串而非 datetime,建议后续添加pd.to_datetime(df_long["Date"])确保时间序列分析兼容性; -
列名一致性:
var_name和value_name必须为合法列名,避免空格或特殊字符(如"On/Off"在部分系统中需加引号,但 pandas 支持); -
性能提示:对超大 Excel 表(>10 万行),可配合
usecols和dtype参数加速读取,例如pd.read_excel(..., usecols="A:D", dtype={"Date": "string"}); -
替代方案对比:
df.stack()也可实现类似效果,但返回 MultiIndex Series,需额外reset_index(),而melt()一步到位、语义更清晰,推荐作为首选。
通过这一标准化流程,你不仅能精准完成当前考勤表重塑,更能掌握 pandas 数据规整的核心范式——让宽变长,让分析更自由。










