Pandy DataFrame
zawiera kolumnę o nazwie, "date"
która zawiera nieunikalne datetime
wartości. Mogę pogrupować linie w tej ramce za pomocą:
data.groupby(data['date'])
Jednak powoduje to podział danych według datetime
wartości. Chciałbym pogrupować te dane według roku zapisanego w kolumnie „data”. Ta strona pokazuje, jak grupować według roku w przypadkach, gdy znacznik czasu jest używany jako indeks, co nie jest prawdą w moim przypadku.
Jak osiągnąć to grupowanie?
Odpowiedzi:
Używam pand 0.16.2. Ma to lepszą wydajność w moim dużym zestawie danych:
Korzystanie z
dt
opcji i zabawy zweekofyear
,dayofweek
itd. Staje się o wiele łatwiejsze.źródło
rozwiązanie ecatmur będzie działać dobrze. Będzie to jednak lepsza wydajność w przypadku dużych zbiorów danych:
data.groupby(data['date'].map(lambda x: x.year))
źródło
map
zwykle ma dobre cechy wydajnościowe przy stosowaniu dowolnych funkcji w porównaniu do zwykłego używaniaapply
.Może to być łatwiejsze do wyjaśnienia za pomocą przykładowego zbioru danych.
Utwórz przykładowe dane
Załóżmy, że mamy jedną kolumnę znaczniki czasu,
date
a inną kolumnę chcielibyśmy przeprowadzić na agregację,a
.df = pd.DataFrame({'date':pd.DatetimeIndex(['2012-1-1', '2012-6-1', '2015-1-1', '2015-2-1', '2015-3-1']), 'a':[9,5,1,2,3]}, columns=['date', 'a']) df date a 0 2012-01-01 9 1 2012-06-01 5 2 2015-01-01 1 3 2015-02-01 2 4 2015-03-01 3
Istnieje kilka sposobów grupowania według roku
year
właściwościądate
indeks i użyj funkcji anonimowej, aby uzyskać dostęp do rokuresample
metody.dt
akcesor zyear
własnościąGdy masz kolumnę (a nie indeks) sygnatur czasowych pand, możesz uzyskać dostęp do wielu dodatkowych właściwości i metod za pomocą
dt
akcesorium. Na przykład:df['date'].dt.year 0 2012 1 2012 2 2015 3 2015 4 2015 Name: date, dtype: int64
Możemy użyć tego do utworzenia naszych grup i obliczenia niektórych agregacji w określonej kolumnie:
df.groupby(df['date'].dt.year)['a'].agg(['sum', 'mean', 'max']) sum mean max date 2012 14 7 9 2015 6 2 3
wstaw datę do indeksu i użyj funkcji anonimowej, aby uzyskać dostęp do roku
Jeśli ustawisz kolumnę daty jako indeks, stanie się ona DateTimeIndex z tymi samymi właściwościami i metodami, jak metoda
dt
akcesora, która daje normalne kolumnydf1 = df.set_index('date') df1.index.year Int64Index([2012, 2012, 2015, 2015, 2015], dtype='int64', name='date')
Co ciekawe, korzystając z metody groupby, możesz przekazać jej funkcję. Ta funkcja zostanie niejawnie przekazana do indeksu DataFrame. Tak więc możemy uzyskać ten sam wynik z góry, wykonując następujące czynności:
df1.groupby(lambda x: x.year)['a'].agg(['sum', 'mean', 'max']) sum mean max 2012 14 7 9 2015 6 2 3
Użyj
resample
metodyJeśli Twoja kolumna daty nie znajduje się w indeksie, musisz określić kolumnę za pomocą
on
parametru. Musisz również określić alias przesunięcia jako ciąg.df.resample('AS', on='date')['a'].agg(['sum', 'mean', 'max']) sum mean max date 2012-01-01 14.0 7.0 9.0 2013-01-01 NaN NaN NaN 2014-01-01 NaN NaN NaN 2015-01-01 6.0 2.0 3.0
Konwertuj na okres pandy
Możesz także przekonwertować kolumnę daty na obiekt Pandy Period. Musimy przekazać alias przesunięcia jako ciąg znaków, aby określić długość okresu.
df['date'].dt.to_period('A') 0 2012 1 2012 2 2015 3 2015 4 2015 Name: date, dtype: object
Następnie możemy użyć tego jako grupy
df.groupby(df['date'].dt.to_period('Y'))['a'].agg(['sum', 'mean', 'max']) sum mean max 2012 14 7 9 2015 6 2 3
źródło
to_period('A')
, po co to („A”)?'A'
is a timeseries offset-alias: pandas.pydata.org/pandas-docs/stable/....dt.year
metodę i zapiszę ją w nowej ramce danych, daty zostaną zapisane jako indeksy i stanie się to problematyczne, jeśli powiem, że muszę wykreślić dane, ponieważ tak naprawdę nie ma kolumny `` daty '', ale tylko trzy dostarczone w.agg()
To powinno działać:
data.groupby(lambda x: data['date'][x].year)
źródło
to też zadziała
data.groupby(data['date'].dt.year)
źródło
<pandas.core.groupby.DataFrameGroupBy object at 0x10d7f6438>
jest tym, co otrzymuję po egzekucji.