2012-12-15 18 views
35

So che posso ottenere i valori univoci di un DataFrame reimpostando l'indice ma esiste un modo per evitare questo passaggio e ottenere direttamente i valori univoci?Ottieni valori univoci dalla colonna indice in MultiIndex

Dato che ho:

 C 
A B  
0 one 3 
1 one 2 
2 two 1 

posso fare:

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

Esiste un modo costruito in panda per fare questo?

+0

non capisco il tuo esempio. uniq_b non viene utilizzato? –

+0

ah, penso di averlo capito. volevi solo "conoscere" i valori unici di B. ok. –

+0

Se è possibile seth, penso che dovresti considerare di cambiare la risposta accettata su 8one6. – KobeJohn

risposta

30

Un modo è quello di utilizzare 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

Funziona per me. Grazie! – seth

+1

Questa è una buona risposta, ma ha alcuni comportamenti molto strani in alcuni casi specifici. Dai un'occhiata alla mia risposta qui sotto per un modo per evitare questi problemi. – 8one6

+0

Questo non funziona per me. L'indice non ha più livelli di attributo. È un aggiornamento? – eleijonmarck

28

risposta di Andy Hayden (index.levels[blah]) è grande per alcuni scenari, ma può portare a comportamento strano in altri. La mia comprensione è che Pandas fa di tutto per riutilizzare gli indici quando è possibile per evitare di avere gli indici di molti DataFrame indicizzati allo stesso modo che occupano spazio nella memoria. Come risultato, I've found the following annoying behavior:

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] 

che emette

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

anziché il previsto

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

Come una persona ha sottolineato dall'altro filo, un linguaggio che sembra molto naturale e funziona correttamente sarebbe:

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

Spero che questo aiuti qualcun altro a schivare il comportamento inaspettato in cui mi sono imbattuto.

+0

FWIW, questo è il comportamento atteso se si cerca di imitare R. In R i livelli delle variabili fattoriali (che assomigliano molto agli indici in panda) non cambiano in subsetting. Si deve esplicitamente reindicizzare per ridurre i possibili livelli. –

Problemi correlati