在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
我对速度很感兴趣(因为我有很多列和很多行)。如果加快排序速度,我也很乐意重新安排数据。非常感谢
答案 0 :(得分:2)
这是一个解决方案,尽管是klugdy:
输入数据帧:
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
答案 1 :(得分:2)
这是一个应该产生良好性能的大多数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