2016-07-10 48 views
5

ho un dataframe della forma:Uso affettatrici su un multi-indice di

Contract Date  
201501 2014-04-29 1416.0 
      2014-04-30 1431.1 
      2014-05-01 1430.6 
      2014-05-02 1443.9 
      2014-05-05 1451.6 
      2014-05-06 1461.4 
      2014-05-07 1456.0 
      2014-05-08 1441.1 
      2014-05-09 1437.8 
      2014-05-12 1445.2 
      2014-05-13 1458.2 
      2014-05-14 1487.6 
      2014-05-15 1477.6 
      2014-05-16 1467.9 
      2014-05-19 1484.9 
      2014-05-20 1470.5 
      2014-05-21 1476.9 
      2014-05-22 1490.0 
      2014-05-23 1473.3 
      2014-05-27 1462.5 
      2014-05-28 1456.3 
      2014-05-29 1460.5 
201507 2014-05-30 1463.5 
      2014-06-02 1447.5 
      2014-06-03 1444.4 
      2014-06-04 1444.7 
      2014-06-05 1455.9 
      2014-06-06 1464.0 

Dove contratto & Data sono rispettivamente indici di tipo int e datetime64.

Quello che voglio è selezionare un intervallo di date. Funziona facendo:

df.reset_index('Contract', drop=True).loc['2014-09'] 

ma io odio questo come perde l'indice/non è molto piacevole (devo fare un sacco di questi).

penso che dovrei essere in grado di fare in questo modo:

df.loc[:,'2014-09'] 

per riportare tutti i dati di settembre 2014. In realtà, questo non funziona. Posso selezionare solo un singolo giorno facendo:

df.loc[:,'2014-09-02'] 

Perché il mio affettatore multidivisione non funziona?

risposta

2

Pandas ha bisogno di essere esplicito se si sta selezionando colonne o sottolivelli di un indice gerarchico. In questo caso, df.loc[:,'2014-09'] non riesce perché i panda cercano di ottenere tutte le righe e quindi cercano una colonna denominata '2014-09' (che non esiste).

Invece, è necessario fornire entrambi i livelli del multiindice e le etichette/slice della colonna.

Per selezionare tutti i dati maggio 2014 dal vostro esempio si potrebbe scrivere:

>>> df.loc[(slice(None), '2014-05'), :]        
Contract Date    
201501 2014-05-01 1430.6 
     2014-05-02 1443.9 
     2014-05-05 1451.6 
     2014-05-06 1461.4 
     2014-05-07 1456.0 
     2014-05-08 1441.1 
     2014-05-09 1437.8 
     2014-05-12 1445.2 
     2014-05-13 1458.2 
     2014-05-14 1487.6 
     2014-05-15 1477.6 
     2014-05-16 1467.9 
     2014-05-19 1484.9 
     2014-05-20 1470.5 
     2014-05-21 1476.9 
     2014-05-22 1490.0 
     2014-05-23 1473.3 
     2014-05-27 1462.5 
     2014-05-28 1456.3 
     2014-05-29 1460.5 
201507 2014-05-30 1463.5 

Qui si traduce in una fetta di [:, '2014-05'] per le righe e [:] per le colonne.

L'oggetto pd.IndexSlice è stato introdotto per rendere questi semantica fetta un po 'più facile:

>>> idx = pd.IndexSlice 
>>> df.loc[idx[:, '2014-05'], :] 
# same slice of DataFrame 
+0

Questo sicuramente lavorare? Come sto provando, sembra che restituisca solo tutti i dati, piuttosto che la rispettiva slice (quindi funzionerà nel tuo esempio con il set di dati limitato, ma non nel mio set di dati espanso). – cjm2671

+0

@ cjm2671, puoi provare a riprodurlo utilizzando il set di dati campione? – MaxU

+1

@ cjm2671: dovrebbe funzionare; Non sono sicuro di come verranno restituite tutte le righe a meno che non sia * slice * anche nel secondo livello, utilizzando una data precedente, ad es. 'df.loc [idx [:, '2013-05':],:]'. Come suggerisce MaxU, forse potresti riprodurre questo problema su un set di dati più piccolo in modo da poter indagare ulteriormente? –

1

Si potrebbe utilizzare .dt accessor per estrarre tutti i valori del mese settembre come segue:

df.loc[(pd.to_datetime(df['Date']).dt.month == 9)] 

vincoli temporali:

timeit df.loc[(pd.to_datetime(df['Date']).dt.month == 5)] 
1000 loops, best of 3: 796 µs per loop 
2

È possibile utilizzare pd.Indexslice per selezionare in base a intervalli per ogni level del vostro MultiIndex in questo modo (see docs):

idx = pd.IndexSlice 
df.loc[idx[:, '2014-05'], :] 

di ottenere:

Contract Date    
201501 2014-05-01 1430.6 
     2014-05-02 1443.9 
     2014-05-05 1451.6 
     2014-05-06 1461.4 
     2014-05-07 1456.0 
     2014-05-08 1441.1 
     2014-05-09 1437.8 
     2014-05-12 1445.2 
     2014-05-13 1458.2 
     2014-05-14 1487.6 
     2014-05-15 1477.6 
     2014-05-16 1467.9 
     2014-05-19 1484.9 
     2014-05-20 1470.5 
     2014-05-21 1476.9 
     2014-05-22 1490.0 
     2014-05-23 1473.3 
     2014-05-27 1462.5 
     2014-05-28 1456.3 
     2014-05-29 1460.5 
201507 2014-05-30 1463.5