如何使用Pandas实现长表与宽表的互相转换
Pandas长表与宽表互相转换实现方案
长表转宽表
你之前用pivot失败的核心原因是缺少同一iso下的pref记录序列标识,补充后即可正常转换,完整实现代码如下:
# 导入依赖 import pandas as pd import numpy as np # 模拟长表数据,可替换为自己的数据源读取逻辑 df_long = pd.DataFrame({ "iso": ["CHN", "CHN", "CHN", "USA", "USA", "ARM"], "pref_name": ["教育", "医疗", "交通", "科技", "农业", np.nan], "pref_score": [92, 87, 78, 95, 82, np.nan] }) # 步骤1:给每个iso分组内的pref记录生成序号,格式化后作为宽表的列名 # 如需按pref_name排序后生成序号,可先执行 df_long = df_long.sort_values(["iso", "pref_name"]) df_long["col_name"] = df_long.groupby("iso").cumcount().apply(lambda x: f"pref_{x+1:02d}") # 步骤2:透视生成宽表 df_wide = df_long.pivot(index="iso", columns="col_name", values="pref_score").reset_index() # 步骤3:补全pref_01-pref_03三列,避免部分iso不足3条pref时缺列 target_cols = ["pref_01", "pref_02", "pref_03"] for col in target_cols: if col not in df_wide.columns: df_wide[col] = np.nan # 调整列顺序得到最终宽表 df_wide = df_wide[["iso"] + target_cols]
如果同一iso下的pref记录超过3条,修改target_cols的列表内容即可适配
宽表转长表
直接使用pandas的melt方法即可实现:
df_long_new = df_wide.melt( id_vars="iso", # 保留为行标识的列 value_vars=["pref_01", "pref_02", "pref_03"], # 需要转为行值的列 var_name="pref_seq", # 存储原列名的字段名 value_name="pref_score" # 存储原列值的字段名 ) # 可选操作:删除空的pref_score记录、去掉多余的pref_seq字段 df_long_new = df_long_new.dropna(subset=["pref_score"]).drop(columns="pref_seq").reset_index(drop=True) # 如果需要还原pref_name字段,和原长表的iso+pref_score对应关系做merge即可
内容的提问来源于stack exchange,提问作者DoctorEXE
相关产品推荐
相关产品推荐

