pandas의 date_range와 resample 메서드를 활용하면 주간 단위 시계열 데이터를 손쉽게 생성하고, 이를 월말(month-end) 빈도로 재표본화하여 각 월의 최댓값을 구할 수 있습니다. 이 글에서는 그 과정을 단계별로 살펴보겠습니다.
문제 정의
다음과 같이 주간(일요일) 단위로 기록된 시계열 데이터가 있을 때,
DataFrame is: Id time_series 0 1 2020-01-05 1 2 2020-01-12 2 3 2020-01-19 3 4 2020-01-26 4 5 2020-02-02 5 6 2020-02-09 6 7 2020-02-16 7 8 2020-02-23 8 9 2020-03-01 9 10 2020-03-08
월말 빈도('M')로 재표본화하면 아래와 같이 각 월의 마지막 날짜를 인덱스로 하는 최댓값 결과를 얻을 수 있습니다.
Maximum month end frequency:
Id time_series
time_series
2020-01-31 4 2020-01-26
2020-02-29 8 2020-02-23
2020-03-31 10 2020-03-08해결 방법
이 문제는 다음 세 단계로 해결할 수 있습니다.
1단계: 데이터프레임 정의
Id 열 하나만 포함된 데이터프레임을 생성합니다.
d = {'Id': [1,2,3,4,5,6,7,8,9,10]}
df = pd.DataFrame(d)2단계: date_range로 시계열 열 생성
pd.date_range() 함수에 시작 날짜(start='01/01/2020'), 생성할 기간 수(periods=10), 그리고 빈도(freq='W')를 지정합니다. freq='W'는 주간(일요일) 빈도를 의미하므로, 2020년 1월 5일부터 매주 일요일 날짜 10개가 생성되어 df['time_series'] 열에 저장됩니다.
df['time_series'] = pd.date_range('01/01/2020', periods=10, freq='W')3단계: resample로 월말 최댓값 계산
resample() 메서드에 on='time_series' 옵션을 지정해 time_series 열을 기준으로 재표본화하고, 'M'(월말) 빈도를 적용한 뒤 max()로 각 그룹의 최댓값을 구합니다.
df.resample('M', on='time_series').max()전체 코드
아래 전체 구현 예제를 통해 더 자세히 이해해 보겠습니다.
import pandas as pd
d = {'Id': [1,2,3,4,5,6,7,8,9,10]}
df = pd.DataFrame(d)
df['time_series'] = pd.date_range('01/01/2020',
periods=10,
freq='W')
print("DataFrame is:\n", df)
print("Maximum month end frequency:")
print(df.resample('M', on='time_series').max())실행 결과
DataFrame is:
Id time_series
0 1 2020-01-05
1 2 2020-01-12
2 3 2020-01-19
3 4 2020-01-26
4 5 2020-02-02
5 6 2020-02-09
6 7 2020-02-16
7 8 2020-02-23
8 9 2020-03-01
9 10 2020-03-08
Maximum month end frequency:
Id time_series
time_series
2020-01-31 4 2020-01-26
2020-02-29 8 2020-02-23
2020-03-31 10 2020-03-08결과 해석 및 참고 사항
재표본화 결과의 인덱스는 각 월의 마지막 날(예: 2020-01-31, 2020-02-29, 2020-03-31)이며, 값은 해당 월에 속한 데이터 중 최댓값입니다. 예를 들어 1월에는 Id 1~4의 데이터가 포함되며, 그중 Id의 최댓값은 4, time_series의 최댓값은 2020-01-26입니다.
참고: pandas 2.2 버전부터는 월말 빈도 별칭 'M'이 더 이상 권장되지 않으므로(deprecated), 대신 'ME'(Month End)를 사용하는 것이 좋습니다. 즉, df.resample('ME', on='time_series').max()처럼 작성하면 됩니다.