3 回答
TA贡献1982条经验 获得超2个赞
一种选择是melt,set_index和unstack:
u = df.melt(['ticker', 'source', 'timestamp'])
(u.set_index(u.columns.difference({'value'}).tolist())['value']
.unstack([1, 0, -1])
.sort_index(axis=1))
ticker A B
source LSE LSE
variable PX_CLOSE PX_LAST PX_OPEN PX_CLOSE PX_LAST PX_OPEN
timestamp
20180101 3 1 2 9 7 8
20180102 6 4 5 12 10 11
或melt, 和pivot_table:
u = df.melt(['ticker', 'source', 'timestamp'])
u.pivot_table(index='timestamp',
columns=['ticker','source','variable'],
values='value')
ticker A B
source LSE LSE
variable PX_CLOSE PX_LAST PX_OPEN PX_CLOSE PX_LAST PX_OPEN
timestamp
20180101 3 1 2 9 7 8
20180102 6 4 5 12 10 11
TA贡献1843条经验 获得超7个赞
您的解决方案应该稍作更改 - 中的列顺序set_index,省略第二个swaplevel并添加sort_index:
df = (df.set_index(['timestamp', 'source', 'ticker'])
.unstack(level=[1,2])
.swaplevel(0,2,axis=1)
.sort_index(axis=1)
)
print (df)
ticker A B
source LSE LSE
PX_CLOSE PX_LAST PX_OPEN PX_CLOSE PX_LAST PX_OPEN
timestamp
20180101 3 1 2 9 7 8
20180102 6 4 5 12 10 11
TA贡献1821条经验 获得超4个赞
我的提议是通过以下方式更改您的解决方案:
第 1 步:df.set_index(['timestamp', 'ticker', 'source']).unstack([1, 2]),就像您所做的那样。
它将列保留为以下形状:
PX_LAST PX_OPEN PX_CLOSE
ticker A B A B A B
source LSE LSE LSE LSE LSE LSE
(并timestamp作为索引)。
第 2 步:reorder_levels([1, 2, 0], axis=1),而不是您的 2 条 swaplevel说明。
它将列保留为:
ticker A B A B A B
source LSE LSE LSE LSE LSE LSE
PX_LAST PX_LAST PX_OPEN PX_OPEN PX_CLOSE PX_CLOSE
最后一步是 sort_index(axis=1, level=[0,1], sort_remaining=False)
请注意,您只对级别 0 和 1 进行排序,因此最后级别的顺序保持不变(PX_LAST、PX_OPEN、PX_CLOSE)。
所以整个脚本(即一条指令)是:
df2 = df.set_index(['timestamp', 'ticker', 'source']).unstack([1, 2])\
.reorder_levels([1, 2, 0], axis=1)\
.sort_index(axis=1, level=[0,1], sort_remaining=False)
当你打印结果时,你会得到:
ticker A B
source LSE LSE
PX_LAST PX_OPEN PX_CLOSE PX_LAST PX_OPEN PX_CLOSE
timestamp
20180101 1 2 3 7 8 9
20180102 4 5 6 10 11 12
添加回答
举报