2015-10-18 16 views
7

Esistono molte registrazioni sull'affinamento del livello [0] di un multiindice di un intervallo di livello 1. Tuttavia, non riesco a trovare una soluzione per il mio problema; cioè, ho bisogno di un intervallo del livello 1 indice per i valori dell'indice del livello [0]I panda di Python dividono il multiindice per l'indice di secondo livello (o qualsiasi altro livello)

dataframe: il primo è dalla A alla Z, il grado è da 1 a 400; Ho bisogno dei primi 2 e degli ultimi 2 per ogni livello [0] (Primo), ma non nello stesso passo.

  Title Score 
First Rank 
A  1 foo 100 
     2 bar 90 
     3 lime 80 
     4 lame 70 
B  1 foo 400 
     2 lime 300 
     3 lame 200 
     4 dime 100 

io sto cercando di ottenere le ultime 2 righe per ogni indice di livello 1 con il codice qui sotto, ma fette correttamente solo per il primo [0] valore di livello.

[IN] df.ix[x.index.levels[1][-2]:] 
[OUT] 
       Title Score 
    First Rank 
    A  3 lime 80 
      4 lame 70 
    B  1 foo 400 
      2 lime 300 
      3 lame 200 
      4 dime 100 

Le prime 2 file ottengo scambiando gli indici, ma non riesco a farlo funzionare per le ultime 2 righe.

df.index = df.index.swaplevel("Rank", "First") 
df= df.sortlevel() #to sort by Rank 
df.ix[1:2] #Produces the first 2 ranks with 2 level[1] (First) each. 
      Title Score 
Rank First 
1  A foo 100 
     B foo 400 
2  A bar 90 
     B lime 300 

Certo che posso scambiare questo torna a ottenere questo:

df2 = df.ix[1:2] 
df2.index = ttt.index.swaplevel("First","rank") #change the order of the indices back. 
df2.sortlevel() 
       Title Score 
    First Rank 
    A  1 foo 100 
      2 bar 90 
    B  1 foo 400 
      2 lime 300 

Ogni aiuto è apprezzato per ottenere la stessa procedura:

  • Ultimi 2 file per l'indice 1 (Grado
  • E un modo migliore per ottenere le prime 2 righe

Edit seguente feedback @ako:

Utilizzando pd.IndexSlice rende veramente facile da tagliare qualsiasi indice di livello. Ecco una soluzione più generica e sotto il mio approccio passo-passo per ottenere la prima e l'ultima di due righe. Maggiori informazioni qui: http://pandas.pydata.org/pandas-docs/stable/advanced.html#using-slicers

"""  
Slicing a dataframe at the level[2] index of the 
major axis (row) for specific and at the level[1] index for columns. 

""" 
    df.loc[idx[:,:,['some label','another label']],idx[:,'yet another label']] 

""" 
Thanks to @ako below is my solution, including how I 
get the top and last 2 rows. 
""" 
    idx = pd.IndexSlice 
    # Top 2 
    df.loc[idx[:,[1,2],:] #[1,2] is NOT a row index, it is the rank label. 
    # Last 2 
    max = len(df.index.levels[df.index.names.index("rank")]) # unique rank labels 
    last2=[x for x in range(max-2,max)] 
    df.loc[idx[:,last2],:] #for last 2 - assuming all level[0] have the same lengths. 

risposta

10

Utilizzare un indicizzatore di affettare valori arbitrari in dimensioni arbitrarie - basta passare un elenco con qualunque siano i livelli/valori desiderati sono per quella dimensione.

idx = pd.IndexSlice 
df.loc[idx[:,[3,4]],:] 

      Title Score 
First Rank    
A  3  lime  80 
     4  lame  70 
B  3  lame 200 
     4  dime 100 

Per riprodurre i dati:

from StringIO import StringIO 

s=""" 
First Rank Title Score 
A  1 foo 100 
A  2 bar 90 
A  3 lime 80 
A  4 lame 70 
B  1 foo 400 
B  2 lime 300 
B  3 lame 200 
B  4 dime 100 
""" 
df = pd.read_csv(StringIO(s), 
       sep='\s+', 
       index_col=["First", "Rank"]) 
+2

Con le risposte intorno StackOverflow per l'indicizzazione MultiIndex Pandas, questa soluzione sembra sia il più pulito e piuttosto sottovalutato. –

Problemi correlati