如何将含多组日期与值列的Pandas DataFrame重塑为长格式?
问题描述
现有如下格式的Pandas DataFrame:
import pandas as pd data = [ ["true","penguin","canary","01/01/2000","3","01/02/2000","10","01/03/2000", "4", "01/04/2000","181"], ["false","tiger","prod","02/01/2000","9","02/02/2000","101","02/03/2000","43","02/04/2000","11"] ] df = pd.DataFrame( data, columns=[ "status","team","env","date_1","value_1","date_2","value_2","date_3","value_3","date_4","value_4"])
希望将其转换为以下长格式表格:
| Status | team | env | Date | Value |
|---|---|---|---|---|
| true | penguin | canary | 01/01/2000 | 3 |
| false | tiger | prod | 02/01/2000 | 9 |
| true | penguin | canary | 01/02/2000 | 10 |
| false | tiger | prod | 02/02/2000 | 101 |
| true | penguin | canary | 01/03/2000 | 4 |
| false | tiger | prod | 02/03/2000 | 43 |
| true | penguin | canary | 01/04/2000 | 181 |
| false | tiger | prod | 02/04/2000 | 11 |
尝试使用melt()、stack()和unstack()方法,仅通过df = df.melt(id_vars=["status", "team", "env"])得到了包含变量列(含date_1、value_1等)和值列的结果,未达到预期格式,寻求解决方法。
解决方案
方法1:使用pd.wide_to_long(最优适配)
该方法专门针对前缀+编号的成对列(如date_1/value_1、date_2/value_2)设计,可一步完成转换:
# 转换为长格式 df_long = pd.wide_to_long( df, stubnames=["date", "value"], # 列名的前缀部分 i=["status", "team", "env"], # 保留的标识列 j="seq", # 临时新增的编号列(后续可删除) sep="_" # 前缀与编号的分隔符 ).reset_index() # 清理临时列并调整列名匹配需求 df_long = df_long.drop("seq", axis=1).rename(columns={ "status": "Status", "date": "Date", "value": "Value" }) # 按日期排序(可选,匹配示例顺序) df_long = df_long.sort_values("Date").reset_index(drop=True)
运行后即可得到与预期完全一致的长格式表格。
方法2:基于melt的后续处理
如果坚持使用melt,可通过拆分变量列、再透视还原成对字段:
# 先执行melt得到基础长格式 melted = df.melt( id_vars=["status", "team", "env"], var_name="variable", value_name="value" ) # 拆分变量列为「类型(date/value)」和「编号」 melted[["type", "seq"]] = melted["variable"].str.split("_", expand=True) # 透视还原date和value的对应关系 df_long = melted.pivot( index=["status", "team", "env", "seq"], columns="type", values="value" ).reset_index().drop("seq", axis=1) # 调整列名并排序 df_long = df_long.rename(columns={ "status": "Status", "date": "Date", "value": "Value" }).sort_values("Date").reset_index(drop=True)
此方法也能达成目标,但步骤更繁琐,优先推荐第一种方案。
内容的提问来源于stack exchange,提问作者John Henry Erikson
相关产品推荐
相关产品推荐

