Rozważ plik CSV:
string,date,number
a string,2/5/11 9:16am,1.0
a string,3/5/11 10:44pm,2.0
a string,4/22/11 12:07pm,3.0
a string,4/22/11 12:10pm,4.0
a string,4/29/11 11:59am,1.0
a string,5/2/11 1:41pm,2.0
a string,5/2/11 2:02pm,3.0
a string,5/2/11 2:56pm,4.0
a string,5/2/11 3:00pm,5.0
a string,5/2/14 3:02pm,6.0
a string,5/2/14 3:18pm,7.0
Mogę to przeczytać i przeformatować kolumnę z datą na format daty i godziny:
b=pd.read_csv('b.dat')
b['date']=pd.to_datetime(b['date'],format='%m/%d/%y %I:%M%p')
Próbowałem pogrupować dane według miesięcy. Wygląda na to, że powinien istnieć oczywisty sposób dostępu do miesiąca i grupowania według niego. Ale nie mogę tego zrobić. Czy ktoś wie jak?
To, czego obecnie próbuję, to ponowne indeksowanie według daty:
b.index=b['date']
Mam dostęp do miesiąca w następujący sposób:
b.index.month
Jednak wydaje mi się, że nie mogę znaleźć funkcji, która mogłaby łączyć się w całość według miesiąca.
python
pandas
datetime
pandas-groupby
atomh33ls
źródło
źródło
resample
(gdy zapewnia potrzebną funkcjonalność), albo użycieTimeGrouper
:df.groupby(pd.TimeGrouper(freq='M'))
df.groupby(pd.TimeGrouper(freq='M')).sum()
lubdf.groupby(pd.TimeGrouper(freq='M')).mean()
pd.TimeGrouper
został uznany za przestarzały na korzyśćpd.Grouper
, który jest nieco bardziej elastyczny, ale nadal przyjmujefreq
ilevel
argumentuje.to_datetime
.b
po odczytaniu z pliku CSV nadawany jest indeks. Dodajb.index = pd.to_datetime(b['date'],format='%m/%d/%y %I:%M%p')
po liniib = pd.read_csv('b.dat')
. [Właśnie zredagowałem odpowiedź.](aktualizacja: 2018)
Pamiętaj, że
pd.Timegrouper
jest to amortyzowane i zostanie usunięte. Użyj zamiast tego:df.groupby(pd.Grouper(freq='M'))
źródło
freq=...
) tutaj . Niektóre przykłady sąfreq=D
za dni ,freq=B
za dni roboczych ,freq=W
dla tygodni lub nawetfreq=Q
na kwartały .Jednym z rozwiązań pozwalających uniknąć MultiIndex jest utworzenie nowej
datetime
kolumny ustawiania dnia = 1. Następnie pogrupuj według tej kolumny. Trywialny przykład poniżej.df = pd.DataFrame({'Date': pd.to_datetime(['2017-10-05', '2017-10-20']), 'Values': [5, 10]}) # normalize day to beginning of month df['YearMonth'] = df['Date'] - pd.offsets.MonthBegin(1) # two alternative methods df['YearMonth'] = df['Date'] - pd.to_timedelta(df['Date'].dt.day-1, unit='D') df['YearMonth'] = df['Date'].map(lambda dt: dt.replace(day=1)) g = df.groupby('YearMonth') res = g['Values'].sum() # YearMonth # 2017-10-01 15 # Name: Values, dtype: int64
Subtelną zaletą tego rozwiązania jest w przeciwieństwie do tego
pd.Grouper
, że indeks groupera jest normalizowany do początku każdego miesiąca, a nie do końca, dlatego można łatwo wyodrębnić grupy za pomocąget_group
:some_group = g.get_group('2017-10-01')
Obliczenie ostatniego dnia października jest nieco bardziej kłopotliwe.
pd.Grouper
od wersji 0.23 obsługujeconvention
parametr, ale ma to zastosowanie tylko doPeriodIndex
groupera.źródło
Nieco alternatywne rozwiązanie dla @ jpp, ale wyprowadzanie
YearMonth
ciągu:df['YearMonth'] = pd.to_datetime(df['Date']).apply(lambda x: '{year}-{month}'.format(year=x.year, month=x.month)) res = df.groupby('YearMonth')['Values'].sum()
źródło