2012-12-15 20 views
35

インデックスをリセットすることによってDataFrameというユニークな値を得ることができますが、この手順を回避して一意の値を直接取得する方法はありますか?MultiIndexのインデックス列から一意の値を取得

私にできること
 C 
A B  
0 one 3 
1 one 2 
2 two 1 

df = df.reset_index() 
uniq_b = df.B.unique() 
df = df.set_index(['A','B']) 

はこれを行うにはパンダに建てられた方法はあります

は、私が持って考えると?

+0

私はあなたの例を理解していません。 uniq_bは使用されていませんか? –

+0

ああ、私はそれを得ると思います。あなたはB. okのユニークな値を '知る'ことを望んでいました。 –

+0

セスの可能性がある場合は、受け入れられた回答を8one6に変更することを検討する必要があります。 – KobeJohn

答えて

30

一つの方法は、index.levelsを使用することです:

In [11]: df 
Out[11]: 
     C 
A B  
0 one 3 
1 one 2 
2 two 1 

In [12]: df.index.levels[1] 
Out[12]: Index([one, two], dtype=object) 
+0

私のために働く。ありがとう! – seth

+1

これは良い答えですが、いくつかの特定のケースでは非常に奇妙な動作をします。これらの問題を回避する方法については、私の答えを見てください。 – 8one6

+0

これは私のためには機能しません。インデックスには属性レベルがありません。これは更新ですか? – eleijonmarck

28

アンディ・ヘイデンの答え(index.levels[blah]は)いくつかのシナリオのための素晴らしいですが、他人に奇妙な行動につながることができます。私の理解では、Pandasは、同様に索引付けされた多数のDataFramesの索引にメモリー内の領域を占有することを避けるために、できる限りインデックスを「再利用」することに長らく関わっています。

import pandas as pd 
import numpy as np 

np.random.seed(0) 

idx = pd.MultiIndex.from_product([['John', 'Josh', 'Alex'], list('abcde')], 
           names=['Person', 'Letter']) 
large = pd.DataFrame(data=np.random.randn(15, 2), 
        index=idx, 
        columns=['one', 'two']) 
small = large.loc[['Jo'==d[0:2] for d in large.index.get_level_values('Person')]] 

print small.index.levels[0] 
print large.index.levels[0] 

Index([u'Alex', u'John', u'Josh'], dtype='object') 
Index([u'Alex', u'John', u'Josh'], dtype='object') 

むしろ1人が他のスレッド上で指摘したように期待

Index([u'John', u'Josh'], dtype='object') 
Index([u'Alex', u'John', u'Josh'], dtype='object') 

より出力し、1つのイディオム非常に自然なようだと:I've found the following annoying behavior結果、正しく動作する:

small.index.get_level_values('Person').unique() 
large.index.get_level_values('Person').unique() 

これは、他の誰かが私が遭遇した超予期しない動作をかわすのを助けることを望みます。

+0

FWIW、これはRを模倣しようとすると予想される振る舞いである.Rでは因子変数(パンダの指数によく似ている)のレベルは部分集合のときに変化しない。可能なレベルを縮小するために、明示的に再索引付けする必要があります。 –