2016-08-04 9 views
5

マルチインデックスDataFrameをセカンダリレベルの複数の値でスライスしたいとします。たとえば、次のデータフレームに:指定したレベルから複数の値でマルチインデックスデータフレームをスライス

   val1 val2 
ind1 ind2 ind3    
1 6 s1  10  8 
2 7 s1  20  6 
3 8 s2  30  4 
4 9 s2  50  2 
5 10 s3  60  0 

私はind3 == s1またはind3 == s3行のみをスライスしたい:

  val1 val2 
ind1 ind2    
1 6  10  8 
2 7  20  6 
5 10  60  0 

ベスト仮想的なオプションがあるため、.xsに複数の引数を渡すことであろう所望のlevelを明示することが可能である。

私は明らかに、すべてのスライスごとの単一値のデータフレームをCONCATできます

In[2]: pd.concat([df.xs('s1',level=2), df.xs('s3',level=2)]) 
Out[2]: 
      val1 val2 
ind1 ind2    
1 6  10  8 
2 7  20  6 
5 10  60  0 

しかし(a)の以上の2つの値、及び(B)を使用しているとき、それはとても読みやすい退屈ではありません大きなDataFramesの場合、かなり重いです(少なくとも多値スライシングオプションが存在する場合は重い)。ここで

は、データフレーム例を構築するためのコードです:DATAFRAMEから最も選択と同様に

import pandas as pd 
df = pd.DataFrame({'ind1':[1,2,3,4,5], 'ind2':[6,7,8,9,10], 'ind3':['s1','s1','s2','s2','s3'], 'val1':[10,20,30,50,60], 'val2':[8,6,4,2,0]}).set_index(['ind1','ind2','ind3']) 

答えて

7

、あなたはマスクまたはインデクサ(この場合はloc)を使用することができます。

マスクを取得するには、MultiIndexでget_level_valuesdocs)を、その後にisindocs)を使用できます。

m = df.index.get_level_values('ind3').isin(['s1', 's3']) 
df[m].reset_index(level=2, drop=True) 

locを使用するには:

df.loc[(slice(None), slice(None), ['s1', 's3']), :].reset_index(level=2, drop=True) 

両方の出力

  val1 val2 
ind1 ind2    
1 6  10  8 
2 7  20  6 
5 10  60  0 

注:アルベルト・ガルシア・Rabosoの答えに見られるようloc方法も書き込むことができます。多くの人々は、Indexのためにlocの構文と一貫しているので、その構文を好む。両方の構文スタイルについては、the docsで説明します。

+0

おかげのように記述することができます!私は結果w.oを探しています。 'ind3'。 – danielhadar

+0

@danielhadar gotcha - 答えが更新されました。 – Alex

+0

最初のオプションは正常に機能しました - ありがとう! – danielhadar

6

あなたはIndexSliceを使用することができます。

idx = pd.IndexSlice 
result = df.loc[idx[:, :, ['s1', 's3']], idx[:]] 
result.index = result.index.droplevel('ind3') 
print(result) 

出力:

  val1 val2 
ind1 ind2    
1 6  10  8 
2 7  20  6 
5 10  60  0 

上記の2行目にはまた、返信用

result = df.loc(axis=0)[idx[:, :, ['s1', 's3']]] 
+0

'IndexSlice' - nice! – Alex

+0

@ AlbertoGarcia-Rabosoご返信ありがとうございます! 2番目の答えが最初であったので、私はそれを承認しましたが、あなたもうまくいきます。 – danielhadar

関連する問題