
本文介绍如何使用 pandas 的 melt() 方法,将 Excel 中“日期×人员”的宽格式排班表(列名为 Date、Bob、Joe、Jane)高效重塑为“日期、姓名、状态”三字段的长格式结构,适用于后续分析或可视化。
本文介绍如何使用 pandas 的 `melt()` 方法,将 excel 中“日期×人员”的宽格式排班表(列名为 date、bob、joe、jane)高效重塑为“日期、姓名、状态”三字段的长格式结构,适用于后续分析或可视化。
在数据分析中,原始数据常以宽格式(wide format)存储——即每个人员占据一列,日期作为行索引;但多数统计建模、时间序列分析或图表绘制(如 seaborn 的 catplot 或 lineplot)更依赖长格式(long format),即每行代表一个观测单元(如“某人在某日是否在岗”)。本教程以员工排班表为例,演示从宽到长的标准重塑流程。
✅ 核心操作:pd.melt() 一步完成结构转换
假设你已将 Excel 文件(如 schedule.xlsx)保存在本地,首先读入数据并查看结构:
import pandas as pd
df = pd.read_excel("schedule.xlsx")
print(df.head())
# 输出示例:
# Date Bob Joe Jane
# 0 1/1/2025 0 0 0
# 1 1/2/2025 1 1 1
# 2 1/3/2025 1 1 1
接着,使用 pd.melt() 将除 "Date" 外的所有人员列“折叠”为两列:variable(原列名)和 value(对应单元格值):
df_long = pd.melt(
df,
id_vars="Date", # 保持不变的标识列(不参与重塑)
var_name="Name", # 指定原列名映射后的新列名(默认为 'variable')
value_name="On/Off" # 指定原单元格值映射后的新列名(默认为 'value')
)
? 关键参数说明:
id_vars: 列名字符串或列表,表示需保留为“主键”的列(此处仅"Date");var_name: 自定义新列名,用于存放原列标题(如"Bob"、"Joe");value_name: 自定义新列名,用于存放原单元格数值(0或1)。
执行后,df_long 即为符合要求的长格式 DataFrame:
| Date | Name | On/Off |
|---|---|---|
| 1/1/2025 | Bob | 0 |
| 1/2/2025 | Bob | 1 |
| 1/3/2025 | Bob | 1 |
| 1/1/2025 | Joe | 0 |
| 1/2/2025 | Joe | 1 |
| ... | ... | ... |
⚠️ 注意事项与最佳实践
-
列名一致性:确保
id_vars中指定的列名(如"Date")严格匹配原始 Excel 表头(区分大小写与空格);若含空格或特殊字符,可用df.columns = df.columns.str.strip()预处理。 -
日期类型处理:
read_excel()默认可能将日期读为字符串。如需后续时间运算,建议添加parse_dates=["Date"]参数:df = pd.read_excel("schedule.xlsx", parse_dates=["Date"]) -
导出结果:可直接保存为 CSV 供其他工具使用(
index=False避免写入行号):df_long.to_csv("schedule_long.csv", index=False, encoding="utf-8-sig") -
替代方法对比:虽然
df.stack()也可实现类似效果,但melt()语义更清晰、参数更直观,是官方推荐的宽→长标准方法;而pivot()和unstack()主要用于长→宽逆向操作。
通过这一简洁流程,你不仅能精准完成排班表重塑,还可复用于任何类似场景(如销售数据按区域/产品展开、问卷结果按题项展开等),大幅提升数据预处理效率。










