Pandas 多索引排序

Posted

技术标签:

【中文标题】Pandas 多索引排序【英文标题】:Pandas multiindex sort 【发布时间】:2017-08-29 20:30:46 【问题描述】:

在 Pandas 0.19 中,我有一个带有以下形式的 Multiindex 的大型数据框

          C0     C1     C2
A   B
bar one   4      2      4
    two   1      3      2
foo one   9      7      1
    two   2      1      3

我想根据“二”对 bar 和 foo(以及更多的双线)进行排序以获得以下结果:

          C0     C1     C2
A   B
bar one   4      4      2
    two   1      2      3
foo one   7      9      1
    two   1      2      3

我对速度很感兴趣(因为我有很多列和很多对行)。如果可以加快排序速度,我也很高兴重新排列数据。非常感谢

【问题讨论】:

【参考方案1】:

这是一个主要是 numpy 的解决方案,应该会产生良好的性能。它首先只选择“两”行并对它们进行 argsorts。然后它为原始数据帧的每一行设置此顺序。然后它解开这个顺序(在添加一个常数来偏移每一行之后)和原始数据帧值。然后,它会根据这个解开的、偏移量和 argsorted 的数组对所有原始值进行重新排序,然后再创建一个具有预期排序顺序的新数据框。

rows, cols = df.shape
df_a = np.argsort(df.xs('two', level=1))
order = df_a.reindex(df.index.droplevel(-1)).values
offset = np.arange(len(df)) * cols
order_final = order + offset[:, np.newaxis]
pd.DataFrame(df.values.ravel()[order_final.ravel()].reshape(rows, cols), index=df.index, columns=df.columns)

输出

         C0  C1  C2
A   B              
bar one   4   4   2
    two   1   2   3
foo one   7   9   1
    two   1   2   3

一些速度测试

# create much larger frame
import string
idx = pd.MultiIndex.from_product((list(string.ascii_letters), list(string.ascii_letters) + ['two']))
df1 = pd.DataFrame(index=idx, data=np.random.rand(len(idx), 3), columns=['C0', 'C1', 'C2'])

#scott boston
%timeit df1.groupby(level=0).apply(sortit)
10 loops, best of 3: 199 ms per loop

#Ted
1000 loops, best of 3: 5 ms per loop

【讨论】:

【参考方案2】:

这是一个解决方案,虽然很笨拙:

输入数据框:

         C0  C1  C2
A   B              
bar one   4   2   4
    two   1   3   2
foo one   9   7   1
    two   2   1   3

自定义排序功能:

def sortit(x):
    xcolumns = x.columns.values
    x.index = x.index.droplevel()
    x.sort_values(by='two',axis=1,inplace=True)
    x.columns = xcolumns
    return x

df.groupby(level=0).apply(sortit)

输出:

         C0  C1  C2
A   B              
bar one   4   4   2
    two   1   2   3
foo one   7   9   1
    two   1   2   3

【讨论】:

以上是关于Pandas 多索引排序的主要内容,如果未能解决你的问题,请参考以下文章

Pandas 中的多索引排序

为每个级别对 Pandas 中的多索引进行不同的排序

Python Pandas 按多索引和列排序

Pandas 多索引数据框 - 从多索引中的一个索引中选择最大值

pandas:选择索引,然后选择多索引切片上的列

在遵循特定结构的同时按列对多索引进行排序