我有以下数据框:
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
关于python - 维护 Pandas 多索引数据帧的顺序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47122232/