如何用pandas的stack/unstack结合swaplevel重塑指定DataFrame?
用Pandas的stack/unstack + swaplevel重塑你的DataFrame
嘿,我来帮你一步步拆解怎么完成这个DataFrame的重塑操作~首先我先把你给出的DataFrame补全(给cost1列补了示例值,方便后续演示):
import pandas as pd df = pd.DataFrame({ 'period': {0: pd.Timestamp('2016-05-01'), 1: pd.Timestamp('2017-05-01'), 2: pd.Timestamp('2018-03-01'), 3: pd.Timestamp('2018-04-01'), 4: pd.Timestamp('2016-05-01'), 5: pd.Timestamp('2017-05-01'), 6: pd.Timestamp('2016-03-01'), 7: pd.Timestamp('2016-04-01')}, 'cost2': {0: 15, 1: 144, 2: 44, 3: 34, 4: 13, 5: 11, 6: 12, 7: 13}, 'rev2': {0: 154, 1: 13, 2: 33, 3: 37, 4: 15, 5: 11, 6: 12, 7: 13}, 'cost1': {0: 25, 1: 124, 2: 54, 3: 44, 4: 23, 5: 21, 6: 22, 7: 23} })
第一步:把period设为索引
堆叠操作需要合适的索引基础,先把时间列设为DataFrame的索引:
df = df.set_index('period')
第二步:用stack()把宽表转长表
stack()会把列标签(比如cost1、cost2、rev2)转化为索引的下层,把原来的宽表变成长表结构:
stacked_df = df.stack()
这时候stacked_df的索引是双层结构:第一层是period时间,第二层是指标名称(比如cost2),每个行对应一个时间+指标的数值组合。
第三步:用swaplevel()交换索引层级
如果你想把指标名称放在索引上层,时间放在下层(方便按指标归类查看数据),就用swaplevel()交换两个索引层级的位置:
swapped_df = stacked_df.swaplevel(0, 1)
现在索引变成了(指标名, period),同一指标的所有时间数据会被集中在一起。
第四步:(可选)用unstack()转回宽表
如果想把时间层级重新转回列,得到以“指标”为行、“时间”为列的规整宽表,就用unstack():
final_df = swapped_df.unstack()
这时候你会得到一个每行对应一个指标、每列对应一个时间点的表格,结构更适合做横向对比分析。
完整流程的链式简写
你也可以把这些操作连起来一步到位:
final_df = df.set_index('period').stack().swaplevel(0, 1).unstack()
额外小提示
- 如果只想堆叠特定列(比如只处理
cost开头的列),可以给stack()传参数:stack(['cost1', 'cost2']) unstack()可以指定要展开的层级,比如unstack(0)就是展开第一个索引层级- 默认
stack()会丢弃缺失值,加上dropna=False可以保留缺失值的行
内容的提问来源于stack exchange,提问作者codingknob
相关产品推荐
相关产品推荐

