python - 维护 Pandas 多索引数据帧的顺序

标签 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           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/

相关文章:

python - 抑制 Pandas 的科学记数法?

python - matplotlib:组合不同的图形并将它们放在一个子图中,共享一个共同的图例

python - 如何动态更改 scikit learn 函数的参数,即找到最佳参数

python - 在这种情况下,python 比 C 慢得多的原因是什么?

python - 将日期序列分配给 pandas groupby 组

python - 与新列中起始点的条件增量日期时间差作为整数

python - 您可以使用 loc 选择范围内的列加上范围外的列吗?

python - 如何在 cygwin 下用 python 构建 gevent?

python - 有没有办法用相应的大陆来标记一个区域? Python

python - 对 Pandas DataFrame 中的不同单词进行分组和计数