繁体   English   中英

熊猫多索引数据框的维护顺序

[英]Maintaining Order of a Pandas Multiindex DataFrame

我有以下数据框:

import pandas as pd
import numpy as np

lvl0 = ['foo', 'bar']
lvl1 = ['x', 'y']

cols = pd.MultiIndex.from_product([lvl0, lvl1])
df = pd.DataFrame(np.random.rand(3,4), columns=cols)

产生:

    foo                     bar
    x           y           x           y
0   0.885461    0.613618    0.404915    0.855922
1   0.096102    0.161894    0.786328    0.805401
2   0.035256    0.476391    0.834996    0.826073

我想添加另一列,但是当我将其放置在末尾时:

df [('foo','z')] = np.random.rand(3)

    foo                     bar                     foo
    x           y           x           y           z
0   0.885461    0.613618    0.404915    0.855922    0.782947
1   0.096102    0.161894    0.786328    0.805401    0.898574
2   0.035256    0.476391    0.834996    0.826073    0.407470

而我希望它在视觉上按lvl0列进行分组,如下所示:

    foo                                 bar
    x           y           z           x           y
0   0.885461    0.613618    0.782947    0.404915    0.855922
1   0.096102    0.161894    0.898574    0.786328    0.805401
2   0.035256    0.476391    0.407470    0.834996    0.826073

做这个的最好方式是什么? 我考虑过要事先检查df.columns,按原样列出lvl0列名,然后再像这样重新分配df:

old_col_order = some_sort_of_columns_gymnastics()
df = df[old_col_order]

但是这些看起来很乱,我不能成为第一个想要订购新列的人。 我也考虑过使用sort_index,但是我的原始顺序也不是字典顺序,因此我仍然必须以某种方式找到原始顺序。

In [215]: new_pos = df.columns.get_loc(('foo','y')) + 1

In [216]: df.insert(new_pos, ('foo','z'), np.random.rand(3))

In [217]: df
Out[217]:
        foo                           bar
          x         y         z         x         y
0  0.368823  0.820497  0.192941  0.174843  0.060076
1  0.111381  0.986995  0.163618  0.517629  0.836983
2  0.431267  0.058645  0.223167  0.793508  0.936183

或者,如果我们不知道最后一个子列(本例中的y ):

In [250]: df.insert(len(df.columns.to_series().loc['foo']), ('foo','z'), np.random.rand(3))

In [251]: df
Out[251]:
        foo                           bar
          x         y         z         x         y
0  0.368823  0.820497  0.294450  0.174843  0.060076
1  0.111381  0.986995  0.521423  0.517629  0.836983
2  0.431267  0.058645  0.264008  0.793508  0.936183

演示-让我们在bar列中添加一个z子列:

In [292]: x
Out[292]:
        foo                 bar                 baz
          x         y         x         y         x         y
0  0.368823  0.820497  0.174843  0.060076  0.368823  0.820497
1  0.111381  0.986995  0.517629  0.836983  0.111381  0.986995
2  0.431267  0.058645  0.793508  0.936183  0.431267  0.058645

In [293]: last_subcol = x.columns.to_series().loc['bar'].index[-1]

In [294]: last_subcol
Out[294]: 'y'

In [295]: new_pos = df.columns.get_loc(('bar',last_subcol)) + 1

In [296]: x.insert(new_pos, ('bar','z'), np.random.rand(3))

In [297]: x
Out[297]:
        foo                 bar                           baz
          x         y         x         y         z         x         y
0  0.368823  0.820497  0.174843  0.060076  0.694670  0.368823  0.820497
1  0.111381  0.986995  0.517629  0.836983  0.722398  0.111381  0.986995
2  0.431267  0.058645  0.793508  0.936183  0.126137  0.431267  0.058645

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM