2016-05-17 15 views
0

私は数値のマルチインデックスPandasデータフレームを持っています。私は、データの他の2つのサブセットを使用して、データフレームのサブセット内の各行を順次ソートしたいと考えています。私は、以下の例では、より良い、私は必要なものを説明すると考えている:マルチインデックスのPandas DataFrameのシーケンシャルソート

この例では、データセット考えてみましょう:

      A   B   C   D 
rtr 2015-01-31 -1.085631 -0.204201 1.730024 1.710438 
    2015-02-28 0.997345 1.979348 1.232650 -0.056341 
key1 2015-01-31 6.180000 0.990000 2.440000 1.920000 
    2015-02-28 1.140000 1.810000 4.560000 0.740000 
key2 2015-01-31 86.000000 36.000000 61.000000 34.000000 
    2015-02-28 97.000000 96.000000 48.000000 98.000000 

key1key2、および日付2015-02-28rtrの最後の行を考えてみましょう:

  1. df.loc['key1']では、2つの最大値の列名を取得します。 (すなわち:C、B)
  2. 列スペースからCおよびB列を除外します。 (つまり、残っている列:A、D)
  3. df.loc['key2']で、残りの列スペースで最大値の列名を取得します。 (例:列AとDの値の、Dが大きい - >戻りD)
  4. は、ステップ1および3に見られるカラム名に対応df.loc['rtr']からの値(すなわち、対応するフェッチ:戻るdf.loc['rtr'].loc['20150228',['C','B','D']]
値例えばデータ生成用
In [140]: df.loc['rtr'].loc['20150228',['C','B','D']] 
Out[140]: 
C 1.232650 
B 1.979348 
D -0.056341 
Name: 2015-02-28 00:00:00, dtype: float64 

コード:

## generate data: 
d1,d2,d3 = {},{},{} 
np.random.seed(123) 
for col in list("ABCD"): 
    d1[col] = np.random.randn(2) 
    d2[col] = np.random.gamma(2,3,2).round(2) 
    d3[col] = np.random.random_integers(0,100, 2) 
t_index = pd.date_range(start = '2015-01-31', periods = 2, freq = "M") 

dat1 = pd.DataFrame(d1, index = t_index) 
dat2 = pd.DataFrame(d2, index = t_index) 
dat3 = pd.DataFrame(d3, index = t_index) 

df = pd.concat([dat1, dat2, dat3], keys = ['rtr', 'key1', 'key2']) 
+0

あなたが望むものはまだ明確ではありません。 – piRSquared

+0

こんにちは、あなたはどの部分が不明であるかを明確にすることができますか? –

+1

「2015-01-31」のみのサンプルデータにアスタリスクを適用しました。予想される出力がどのように見えるかをよりよく理解することが役立ちます。回答が必要な質問が表示されたら、その質問に答えるまでにどれくらいの時間がかかるかを判断するために電話をかけます。私はこれを現在の作業負荷とバランスさせます。最後に、私が質問を読んでいるときに私の目が艶をもらえば、私はそれをスキップします。可能な限り誰かが読んで理解しやすいようにすることが、あなたの最大の関心事です。 – piRSquared

答えて

1

ステップ1:指定された日付の問題を解決します。

df1 = df.xs('2015-01-31', level=1) 

columns = df1.loc['key1'].nlargest(2).index.tolist() 
columns.append(df1.loc['key2'][df.columns.difference(columns)].idxmax()) 
df1.loc['rtr', columns] 

我々はnlargestを使用してidxmaxが唯一の最大のために働くため、結果のインデックスを取ります。 pandasのインデックスdifferenceメソッドを使用して前の列を除外した後、次の行にidxmaxを使用します。

手順2groupbyを使用して、上記の解決策を各日付に個別に適用します。

def func(df2): 
    df1 = df2.reset_index(level=1, drop=True) 
    columns = df1.loc['key1'].nlargest(2).index.tolist() 
    columns.append(df1.loc['key2'][df.columns.difference(columns)].idxmax()) 
    return df1.loc['rtr', columns] 

df.groupby(level=1).apply(func) 

xsとは対照的に、groupbyインデックスレベルを低下しない、ためreset_indexを添加します。

+1

優れたソリューション! 2番目のステップで 'nlargest(m).index.tolist()'を使用することになるでしょう。これはもっと大きなデータセットと各キーの複数の選択肢に一般化するためです。代わりに 'np.argsort'と' df.apply'と戦っていたので、私は 'groupby'を使う考えは一度もありませんでした。コードをありがとう! –

関連する問題