2017-04-04 115 views
3

在熊貓0.19我有以下形式的多指標一的大數據幀,根據「兩節」,以大熊貓多指標排序

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

我要排序的酒吧和Foo(多以雙線爲他們)得到以下:

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

我對速度感興趣(因爲我有很多列和許多行對)。如果加快分類速度,我也很樂意重新安排數據。非常感謝

回答

2

這裏大多數人這應該會產生良好的性能。它首先只選擇'兩'行並對它們進行排序。然後它爲原始數據幀的每一行設置此順序。然後解開這個順序(在添加一個常數來抵消每一行之後)和原始數據幀值。然後,在創建具有預定排序順序的新數據幀之前,基於此解開的偏移量和參數數組重新排序所有原始值。

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

這裏是一個解決方案,雖然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