2016-07-10 5 views
5

Ich habe einen Datenrahmen von der Form bekommt:Mit Slicer auf einem Multi-Index

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 

Wo Vertrag & Datum sind Indizes vom Typ int und datetime64 ist.

Ich möchte einen Datumsbereich auswählen. Es funktioniert, indem Sie:

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

Aber ich hasse das, wie es den Index verliert/ist nicht sehr angenehm (ich habe eine Menge von diesen zu tun).

Ich glaube, ich sollte in der Lage sein, es so zu tun:

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

, um alle Daten des September 2014 zu bringen. In Wirklichkeit funktioniert das nicht. Ich kann nur einen einzigen Tag auswählen, indem Sie Folgendes tun:

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

Warum funktioniert meine Multi-Index-Slicer nicht?

Antwort

2

Bei Pandas müssen Sie explizit angeben, ob Sie Spalten oder Unterebenen eines hierarchischen Indexes auswählen. In diesem Fall schlägt df.loc[:,'2014-09'] fehl, da Pandas versucht, alle Zeilen zu erhalten und dann nach einer Spalte mit der Bezeichnung '2014-09' (die nicht existiert) zu suchen.

Stattdessen müssen Sie beide Ebenen des Multi-Index und die Spaltenbeschriftungen/Slice geben.

Um alle Daten Mai 2014 wählen Sie aus Ihrem Beispiel könnten Sie schreiben:

>>> 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 

Hier zu einer Scheibe [:, '2014-05'] für die Zeilen und [:] für die Spalten übersetzt.

Das pd.IndexSlice Objekt eingeführt wurde diese Scheibe Semantik ein wenig leichter zu machen:

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

Ist dies auf jeden Fall funktionieren? Während ich das versuche, scheint es, nur alle Daten zurückzusenden, anstatt den jeweiligen Slice (also wird es in Ihrem Beispiel mit dem begrenzten Datensatz funktionieren, aber nicht mit meinem erweiterten Datensatz). – cjm2671

+0

@ cjm2671, können Sie versuchen, es mit Ihrem Beispieldatensatz zu reproduzieren? – MaxU

+1

@ cjm2671: es sollte funktionieren; Ich bin mir nicht sicher, wie alle Zeilen zurückgegeben werden, es sei denn, Sie schneiden * auch in der zweiten Ebene unter Verwendung eines früheren Datums, z. 'df.loc [idx [:, '2013-05':],:]]. Wie MaxU vorschlägt, könnten Sie dieses Problem möglicherweise auf einem kleineren Datensatz reproduzieren, damit wir weiter nachforschen können? –

1

Sie .dt accessor nutzen könnten alle Werte des Monats September zu extrahieren, wie folgt:

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

Timing:

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

Sie könnenverwendenfür jeden level Ihre MultiIndex wie so (see docs), basierend auf Bereiche wählen:

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

zu erhalten:

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 
Verwandte Themen