Pandy: resample timeseries with groupby
Biorąc pod uwagę poniższy ramka danych pandy:
In [115]: times = pd.to_datetime(pd.Series(['2014-08-25 21:00:00','2014-08-25 21:04:00',
'2014-08-25 22:07:00','2014-08-25 22:09:00']))
locations = ['HK', 'LDN', 'LDN', 'LDN']
event = ['foo', 'bar', 'baz', 'qux']
df = pd.DataFrame({'Location': locations,
'Event': event}, index=times)
df
Out[115]:
Event Location
2014-08-25 21:00:00 foo HK
2014-08-25 21:04:00 bar LDN
2014-08-25 22:07:00 baz LDN
2014-08-25 22:09:00 qux LDN
Chciałbym ponownie pobrać dane, aby agregować je co godzinę według liczby, podczas grupowania według lokalizacji, aby stworzyć ramkę danych, która wygląda tak:
Out[115]:
HK LDN
2014-08-25 21:00:00 1 1
2014-08-25 22:00:00 0 2
Próbowałem różnych kombinacji resample() i groupby (), ale bez powodzenia. Jak mam to zrobić? 3 answers
W moim oryginalnym poście zasugerowałem użycie pd.TimeGrouper
.
Obecnie używa się pd.Grouper
zamiast pd.TimeGrouper
. Składnia jest w dużej mierze taka sama, ale TimeGrouper
jest obecnie przestarzałe na rzecz pd.Grouper
.
Ponadto, podczas gdy pd.TimeGrouper
może grupować tylko według DatetimeIndex, pd.Grouper
może grupować według DateTime kolumny , które można określić poprzez key
parametr .
Przydałby się pd.Grouper
do grupy DatetimeIndex'ed DataFrame według godziny:
grouper = df.groupby([pd.Grouper('1H'), 'Location'])
Użycie count
aby policzyć liczbę zdarzeń w każdej grupie:
grouper['Event'].count()
# Location
# 2014-08-25 21:00:00 HK 1
# LDN 1
# 2014-08-25 22:00:00 LDN 2
# Name: Event, dtype: int64
Użycie unstack
aby przenieść poziom indeksu Location
na poziom kolumny:
grouper['Event'].count().unstack()
# Out[49]:
# Location HK LDN
# 2014-08-25 21:00:00 1 1
# 2014-08-25 22:00:00 NaN 2
A następnie użyj fillna
, aby zmienić Nan na zera.
Składając wszystko razem,
grouper = df.groupby([pd.Grouper('1H'), 'Location'])
result = grouper['Event'].count().unstack('Location').fillna(0)
Location HK LDN
2014-08-25 21:00:00 1 1
2014-08-25 22:00:00 0 2
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-18 21:42:36
Pandy 0.21 odpowiedź: TimeGrouper jest coraz przestarzały
Istnieją dwie opcje, aby to zrobić. W rzeczywistości mogą dawać różne wyniki w oparciu o Twoje dane. Pierwsza opcja grupuje według lokalizacji, a w obrębie lokalizacji grupy według godziny. Druga opcja grupuje jednocześnie według lokalizacji i godziny.
Opcja 1 : Użyj groupby + resample
grouped = df.groupby('Location').resample('H')['Event'].count()
Opcja 2 : Grupuj zarówno lokalizację, jak i dane razem z groupby(pd.Grouper)
grouped = df.groupby(['Location', pd.Grouper(freq='H')])['Event'].count()
Oboje wynik będzie następujący:
Location
HK 2014-08-25 21:00:00 1
LDN 2014-08-25 21:00:00 1
2014-08-25 22:00:00 2
Name: Event, dtype: int64
A następnie przekształcić:
grouped.unstack('Location', fill_value=0)
Wyświetli
Location HK LDN
2014-08-25 21:00:00 1 1
2014-08-25 22:00:00 0 2
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-05 22:38:01
Multiple Column Group By
Untubu jest na miejscu z jego odpowiedzi, ale chciałem dodać, co można zrobić, jeśli masz trzecią kolumnę, powiedzieć Cost
i chciał agregować to jak powyżej. To właśnie dzięki połączeniu odpowiedzi unutbu i tej dowiedziałem się, jak to zrobić i pomyślałem, że podzielę się z przyszłymi użytkownikami.
Utwórz ramkę danych za pomocą Cost
colunm.
In[1]:
import pandas as pd
times = pd.to_datetime(pd.Series(['2014-08-25 21:00:00',
'2014-08-25 21:04:00','2014-08-25 22:07:00','2014-08-25 22:09:00']))
locations = ['HK', 'LDN', 'LDN', 'LDN']
event = ['foo', 'bar', 'baz', 'qux']
cost = [20, 24, 34, 52] # add in cost colunm
df = pd.DataFrame({'Location': locations, 'Event': event, 'Cost': cost}, index=times)
df
Out[1]:
Event Location Cost
2014-08-25 21:00:00 foo HK 20
2014-08-25 21:04:00 bar LDN 24
2014-08-25 22:07:00 baz LDN 34
2014-08-25 22:09:00 qux LDN 52
Teraz grupujemy za pomocą funkcji agg
, aby określić agregację każdej kolumny metoda, tj. count, mean, sum itp.
In[2]:
df = df.groupby([pd.TimeGrouper('1H'), 'Location']).agg({'Event': np.sum,
'Cost': np.mean})
Out[2]:
Location Event Cost
2014-08-25 21:00:00 HK 1 20
LDN 1 24
2014-08-25 22:00:00 LDN 2 43
Następnie finał unstack
z wypełnieniem NaN
z zerami i wyświetlaniem jako int
, ponieważ jest ładny.
In[3]:
df.df.unstack().fillna(0).astype(int)
Out[3]:
Cost Event
Location HK LDN HK LDN
2014-08-25 21:00:00 20 24 1 1
2014-08-25 22:00:00 0 43 0 2
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:26:14