Python 维护多索引数据帧的顺序

Python 维护多索引数据帧的顺序,python,pandas,dataframe,multi-index,Python,Pandas,Dataframe,Multi Index,我有以下数据帧: 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

我有以下数据帧:

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.rand.rand(3)

而我希望它通过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_索引,但是我的原始顺序也不是字典顺序,所以我仍然需要以某种方式找到原始顺序

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
,在本例中):

演示-让我们将
z
子列添加到
bar
列:

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

使用
sort\u index
df=df.sort\u index(level=0,axis=1)
如果我想让它们按字母顺序排列,这是可行的,但我想保持原始(非字母顺序)顺序。在这种情况下,你肯定想要Max的答案。如果有帮助,一定要将其标记为已接受!我本想就不知道最后一个专栏发表评论,但你抢先告诉了我。不过,提出的替代方案并不十分有效,因为它假设我想插入第一个组。虽然我喜欢这个想法,但现在研究如何为任何组进行重构仍然感觉有点难看,但我可以使用“last_subcol=df.loc[df.index[0],“bar'].index[-1]”和“insert_loc=df.columns.get_loc(('bar',z'),np.random.rand(3)),这就把事情联系起来了together@Andrew,普通!我刚刚完成了同样的解决方案,我甚至使用了相同的变量名:
last\u subcol
:-D
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
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