2017-02-02 45 views
5

mam ramkę pandas danych w następujący sposób:Pandy GroupBy godzina dnia do słownika

date    | Item | count 
------------------------------------ 
2016-12-06 10:45:08 | Item1 | 60 
2016-12-06 10:45:08 | Item2 | 145 
2016-12-06 09:45:00 | Item1 | 60 
2016-12-06 09:44:54 | Item3 | 600 
2016-12-06 09:44:48 | Item4 | 15 
2016-12-06 11:45:08 | Item1 | 60 
2016-12-06 10:45:08 | Item2 | 14 
2016-11-06 09:45:00 | Item1 | 62 
2016-11-06 09:44:54 | Item3 | 6 
2016-11-06 09:44:48 | Item4 | 15 

Próbuję GroupBy Pozycje przez powiedzmy godzina dnia (lub później tylko dzień) znać Poniższe statystyki: wykaz przedmiotów sprzedawanych na dzień, takich jak:

  • na 2016-12-06, z 09:00:00 do 10:00:00, Pozycja1, Pozycja 3 Wartość i ITEM4 zostały sprzedane; i tak dalej.
  • Na 2016-12-06 zostały sprzedane Item1, Item2, Item3, Item4 (unique items).

Podczas gdy jestem daleko od pobierania tych statystyk, utknąłem z grupowaniem według czasu. Początkowo print df.dtypes pokazał

date object 
Item object 
count int64 
dtype: object 

Więc użyłem następujący wiersz kodu do konwersji kolumny dat do obiektu data pandy.

df['date'] = pd.to_datetime(df['date']) 

i teraz, print df.dtypes plony:

date datetime64[ns] 
Item object 
count int64 
dtype: object 

Jednak gdy próbuję GroupBy kolumnę date korzystając TimeGrouper wykonując następujące linie kodu

from pandas.tseries.resample import TimeGrouper 
print df.groupby([df['date'],pd.TimeGrouper(freq='Min')]) 

uzyskać następujące TypeError. Zgodnie z sugestiami podanymi here lub here, konwersja przy użyciu pd.to_datetime powinna rozwiązać ten problem.

TypeError: Only valid with DatetimeIndex, TimedeltaIndex or PeriodIndex, but got an instance of 'RangeIndex' 

Nie mam pojęcia, jak rozwiązać ten problem, aby przejść do statystyk, których szukam. Wszelkie wskazówki dotyczące rozwiązania tego błędu i korzystania z TimeGrouper do wyszukiwania statystyk najlepiej w formacie słownika (lub czegoś, co ma więcej sensu) byłyby mile widziane.

Odpowiedz

3

Można użyć groupby przez numpy array - datetimes z usuniętym minutes i seconds:

print (df['date'].values.astype('<M8[h]')) 
['2016-12-06T10' '2016-12-06T10' '2016-12-06T09' '2016-12-06T09' 
'2016-12-06T09' '2016-12-06T11' '2016-12-06T10' '2016-11-06T09' 
'2016-11-06T09' '2016-11-06T09'] 

print (df.groupby(df['date'].values.astype('<M8[h]')).Item.unique()) 
2016-11-06 09:00:00 [Item1, Item3, Item4] 
2016-12-06 09:00:00 [Item1, Item3, Item4] 
2016-12-06 10:00:00   [Item1, Item2] 
2016-12-06 11:00:00     [Item1] 
Name: Item, dtype: object 

print (df.groupby(df['date'].values.astype('<M8[h]')).Item 
     .apply(lambda x: x.unique().tolist()).to_dict()) 
{Timestamp('2016-11-06 09:00:00'): ['Item1', 'Item3', 'Item4'], 
Timestamp('2016-12-06 09:00:00'): ['Item1', 'Item3', 'Item4'], 
Timestamp('2016-12-06 10:00:00'): ['Item1', 'Item2'], 
Timestamp('2016-12-06 11:00:00'): ['Item1']} 

print (df.groupby(df['date'].values.astype('<M8[D]')).Item 
     .apply(lambda x: x.unique().tolist()).to_dict()) 
{Timestamp('2016-11-06 00:00:00'): ['Item1', 'Item3', 'Item4'], 
Timestamp('2016-12-06 00:00:00'): ['Item1', 'Item2', 'Item3', 'Item4']} 

Dziękuję Jeff do korzystania sugestia round:

print (df.groupby(df['date'].dt.round('h')).Item 
     .apply(lambda x: x.unique().tolist()).to_dict()) 

{Timestamp('2016-11-06 10:00:00'): ['Item1', 'Item3', 'Item4'], 
Timestamp('2016-12-06 12:00:00'): ['Item1'], 
Timestamp('2016-12-06 10:00:00'): ['Item1', 'Item3', 'Item4'], 
Timestamp('2016-12-06 11:00:00'): ['Item1', 'Item2']} 

print (df.groupby(df['date'].dt.round('d')).Item 
     .apply(lambda x: x.unique().tolist()).to_dict()) 
{Timestamp('2016-11-06 00:00:00'): ['Item1', 'Item3', 'Item4'], 
Timestamp('2016-12-06 00:00:00'): ['Item1', 'Item2', 'Item3', 'Item4']} 
+0

Przy okazji, naprawdę to lubię. Zapamiętam to na później. – piRSquared

+0

bardziej idiomatyczny w użyciu .round ('min') – Jeff

+0

.dt.round ('min') to metoda na akcesorze – Jeff

3
sold = df.set_index('date').Item.resample('H').agg({'Sold': 'unique'}) 
sold[sold.Sold.str.len() > 0] 

             Sold 
date          
2016-11-06 09:00:00 [Item4, Item3, Item1] 
2016-12-06 09:00:00 [Item4, Item3, Item1] 
2016-12-06 10:00:00   [Item1, Item2] 
2016-12-06 11:00:00    [Item1]