pandas 데이터 프레임 그룹 별 datetime 월


90

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

이것을 읽고 날짜 열을 datetime 형식으로 다시 형식화 할 수 있습니다.

b=pd.read_csv('b.dat')
b['date']=pd.to_datetime(b['date'],format='%m/%d/%y %I:%M%p')

나는 월별로 데이터를 그룹화하려고 노력하고 있습니다. 월에 액세스하고이를 기준으로 그룹화하는 분명한 방법이 있어야 할 것 같습니다. 그러나 나는 그것을 할 수없는 것 같다. 누구든지 방법을 알고 있습니까?

현재 시도하고있는 것은 날짜별로 다시 색인화하는 것입니다.

b.index=b['date']

다음과 같이 달에 액세스 할 수 있습니다.

b.index.month

그러나 나는 월별로 함께 묶는 기능을 찾지 못하는 것 같습니다.

답변:


174

관리 :

b = pd.read_csv('b.dat')
b.index = pd.to_datetime(b['date'],format='%m/%d/%y %I:%M%p')
b.groupby(by=[b.index.month, b.index.year])

또는

b.groupby(pd.Grouper(freq='M'))  # update for v0.21+

51
좀 더 유행적인 방법은 resample(필요한 기능을 제공 할 때) 사용하거나 다음을 사용하는 것입니다 TimeGrouper.df.groupby(pd.TimeGrouper(freq='M'))
Karl D.

10
결과 DataFrame 합계 또는 평균을 얻으려면 df.groupby(pd.TimeGrouper(freq='M')).sum()또는df.groupby(pd.TimeGrouper(freq='M')).mean()
Alexandre

9
pd.TimeGrouper은 (는) 더 이상 사용되지 pd.Grouper않지만 더 유연하지만 여전히 인수 freqlevel인수입니다.
BallpointBen

첫 번째 방법은 작동하지 않는 것 같습니다. 를 통해 생성 된 Series에 대해 'Series object has no attribute'month '라는 오류가 발생합니다 to_datetime.
ely

1
@ely 대답 b은 CSV에서 읽은 후 색인이 주어진 원래 질문의 줄에 암시 적으로 의존합니다 . b.index = pd.to_datetime(b['date'],format='%m/%d/%y %I:%M%p')줄 뒤에 추가하십시오 b = pd.read_csv('b.dat'). [지금도 답변을 수정했습니다.]
goodside

71

(업데이트 : 2018)

참고 pd.Timegrouper감가 상각 및 제거됩니다. 대신 사용 :

 df.groupby(pd.Grouper(freq='M'))

2
여기 에서 Grouper 문서를 찾고 여기 에서 주파수 사양 ( freq=...)을 찾으 십시오 . 몇 가지 예 freq=D를 위해 , freq=B대한 , freq=W대한 또는 freq=Q위해 분기 .
Kim

1
다음과 같이 df를 다시 인덱싱 할 필요가 없도록 'key'를 사용하는 것이 유용하다는 것을 알았습니다. df.groupby (pd.Grouper (key = 'your_date_column', freq = 'M'))
Edward

10

MultiIndex를 피하는 한 가지 해결책은 datetimeday = 1로 설정 하는 새 열 을 만드는 것 입니다. 그런 다음이 열을 기준으로 그룹화합니다. 아래의 간단한 예.

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

이 솔루션의 미묘한 이점은과 달리 pd.Grouper그룹화 색인이 매월 끝이 아닌 초순 으로 정규화 되므로 다음을 통해 그룹을 쉽게 추출 할 수 있다는 것입니다 get_group.

some_group = g.get_group('2017-10-01')

10 월 마지막 날을 계산하는 것은 약간 더 번거 롭습니다. pd.Grouperv0.23부터는 convention매개 변수를 지원 하지만 이는 PeriodIndex그룹화 에만 적용됩니다 .


8

@jpp에 대한 약간의 대안 솔루션이지만 YearMonth문자열을 출력 합니다.

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()
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.