如何设置和分组Pandas多级列?

2024-06-16 15:01:01 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个数据帧的形状是这样的:

   PX_LAST PX_OPEN PX_CLOSE ticker source timestamp
0        1       2        3      A   LSE   20180101
1        4       5        6      A   LSE   20180102
1        7       8        9      B   LSE   20180101
1       10      11       12      B   LSE   20180102
....

我想把它按摩成以下格式:

^{pr2}$

我首先尝试使用set_index将ticker和source列设置为行索引,然后使用unstack将它们推到似乎有效的列轴上

df.set_index(['timestamp', 'ticker', 'source'])
    .unstack(level=[1,2])
    .swaplevel(0,1,axis=1)
    .swaplevel(1,2,axis=1)

这确实很好,但有两个问题:1)它非常冗长,需要进行所有的swaplevel调用才能使列保持正确的形状。2) 它似乎没有像我希望的那样进行分组,也就是说,我得到的结果是这样的:

              LSE     LSE      LSE      LSE ...
          PX_LAST PX_LAST PX_CLOSE PX_CLOSE ...
timestamp 
20180101       1        7        2       8  ...
20180102       4        8        5      11  ...

有没有一种更干净的方法来实现我想要的格式?在


Tags: 数据sourcecloseindex格式timestamplastticker
3条回答

您的解决方案应该有一点改变-使用set_index中列的顺序,省略第二个swaplevel并添加{a1}:

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

一个选项是meltset_indexunstack

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

^{pr2}$

我的建议是通过以下方式改变您的解决方案:

第一步: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作为索引)。在

第二步:reorder_levels([1, 2, 0], axis=1),而不是你的2 swaplevel指令。在

它将列保留为:

^{pr2}$

最后一步是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)

打印结果时,您将得到:

^{4}$

相关问题 更多 >