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