2017-04-04 28 views
3

をマルチインデックス「2」に記載のパンダは、私は次の形式のマルチインデックスを持つ大規模なデータフレームを持っているパンダ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

ここでは、ほとんどがn優れた性能を発揮する頑丈なソリューションです。最初に '2つの'行のみを選択し、それらをargsortします。次に、元のデータフレームの各行に対してこの順序を設定します。次に、この順序(各行をオフセットする定数を追加した後)と元のデータフレーム値を解きます。その後、意図されたソート順で新しいデータフレームを作成する前に、このunraveled、offsetおよび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

は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 
関連する問題