2016-07-10 16 views
5

Mam dataframe w postaci:Korzystanie krajalnice na 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 

Gdzie kontraktu & Data są indeksy typu int i datetime64 odpowiednio.

To, czego chcę, to wybrać zakres dat. To działa, wykonując:

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

Ale nienawidzę tego jak traci indeks/nie jest bardzo przyjemny (muszę zrobić wiele z nich).

myślę, że powinienem być w stanie zrobić to tak:

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

przywrócić wszystkie dane września 2014 roku. W rzeczywistości to nie działa. Mogę wybrać tylko jeden dzień, wykonując:

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

Dlaczego moja krajarka wielo-indeksowa nie działa?

Odpowiedz

2

Pandy muszą jasno określać, czy wybierasz kolumny lub podpoziomy hierarchicznego indeksu. W tym przypadku, df.loc[:,'2014-09'] nie powiedzie się, ponieważ panda próbuje uzyskać wszystkie wiersze, a następnie wyszukać kolumnę o nazwie '2014-09' (która nie istnieje).

Zamiast tego należy podać obydwa poziomy wielopoziomowego zestawu znaków: i w etykietach kolumn/plasterkach.

Aby zaznaczyć wszystkie dane maja 2014 roku ze swojego przykład można napisać:

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

Tutaj przekłada się plasterka [:, '2014-05'] dla wierszy i [:] dla kolumn.

Przedmiotem pd.IndexSlice zostało wprowadzone, aby te semantyka slice trochę łatwiej:

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

Czy to na pewno działa? Kiedy próbuję tego, wydaje się, że po prostu zwraca wszystkie dane, a nie odpowiedni plaster (tak będzie działać w twoim przykładzie z ograniczonym zbiorem danych, ale nie w moim rozszerzonym zbiorze danych). – cjm2671

+0

@ cjm2671, czy możesz spróbować odtworzyć go przy użyciu przykładowego zestawu danych? – MaxU

+1

@ cjm2671: powinno działać; Nie jestem pewien, w jaki sposób wszystkie wiersze zostaną zwrócone, chyba że * plaster * również na drugim poziomie, przy użyciu wcześniejszej daty, np. 'df.loc [idx [:, '2013-05':],:]'. Jak sugeruje MaxU, być może mógłbyś odtworzyć ten problem na mniejszym zbiorze danych, abyśmy mogli zbadać dalej? –

1

Można użyć .dt accessor wydobyć wszystkie wartości miesiąca września następująco:

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

ograniczenia czasowe:

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

Możesz użyć pd.Indexslice do wybrania na podstawie zakresów dla każdej level swojej MultiIndex jak tak (see docs):

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

dostać:

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