如何实现比pd.pivot更宽的Pandas数据重塑并自定义列名?
问题
现有两个地区(na、eu)的数据集,各包含3个物品的3项统计数据:
import pandas as pd na = pd.DataFrame({ 'item':['a','b','c'], 'stat1':[3,9,4], 'stat2':[84,23,55], 'stat3':[131,293,201] }) # na 数据集 # item stat1 stat2 stat3 # 0 a 3 84 131 # 1 b 9 23 293 # 2 c 4 55 201 eu = pd.DataFrame({ 'item':['a','b','c'], 'stat1':[5,1,7], 'stat2':[34,61,29], 'stat3':[839,531,339] }) # eu 数据集 # item stat1 stat2 stat3 # 0 a 5 34 839 # 1 b 1 61 531 # 2 c 7 29 339
希望将数据重塑为每行对应一个地区,列名为物品.统计项的格式,最终结果如下:
final = pd.DataFrame({ 'region': ['na','eu'], 'a.stat1': [3,5], 'a.stat2': [84,34], 'a.stat3': [131,839], 'b.stat1': [9,1], 'b.stat2': [23,61], 'b.stat3': [293,531], 'c.stat1': [4,7], 'c.stat2': [55,29], 'c.stat3': [201,339] }) # 最终结果 # region a.stat1 a.stat2 a.stat3 b.stat1 b.stat2 b.stat3 c.stat1 c.stat2 c.stat3 # 0 na 3 84 131 9 23 293 4 55 201 # 1 eu 5 34 839 1 61 531 7 29 339
尝试用pd.pivot/pivot_table无法实现该需求,请问该如何操作?
解决方案
可以通过「合并数据→转长格式→透视重组→列名合并」四步实现,具体代码如下:
步骤1:为数据集添加地区标记并合并
先给每个地区的DataFrame添加region列,再合并成一个数据集:
na['region'] = 'na' eu['region'] = 'eu' combined = pd.concat([na, eu], ignore_index=True)
步骤2:将宽格式转为长格式
用melt把stat1/stat2/stat3这类统计项转为行数据,方便后续组合列名:
melted = combined.melt(id_vars=['region', 'item'], var_name='stat', value_name='value')
步骤3:透视重组数据
以region为行索引,item和stat组合为列,完成数据的宽格式转换:
pivoted = melted.pivot(index='region', columns=['item', 'stat'], values='value')
步骤4:合并列名并重置索引
把多级列名合并成物品.统计项的格式,再将region从索引转回普通列:
pivoted.columns = pivoted.columns.map('.'.join) final = pivoted.reset_index()
简洁链式写法
如果想简化代码,可以用链式调用一次性完成:
final = (pd.concat([na.assign(region='na'), eu.assign(region='eu')], ignore_index=True) .melt(id_vars=['region', 'item'], var_name='stat') .pivot(index='region', columns=['item', 'stat'], values='value') .rename_axis(columns=None) .reset_index()) final.columns = final.columns.map('.'.join)
运行以上代码后,得到的final就是你需要的目标格式。
内容的提问来源于stack exchange,提问作者ZtoYi
相关产品推荐
相关产品推荐

