[Python pandas] 일정한 주기의 시계열 데이터 Series, DataFrame 만들기
Python 분석과 프로그래밍/Python 데이터 전처리 2019. 12. 24. 18:29지난번 포스팅에서는 Python pandas의 Series, DataFrame에서 시계열 데이터 index 의 중복 확인 및 처리하는 방법(https://rfriend.tistory.com/500) 에 대해서 소개하였습니다.
이번 포스팅에서는 Python pandas에서 일정한 주기의 시계열 데이터(Fixed frequency time series)를 가진 Series, DataFrame 만드는 방법을 소개하겠습니다.
[ 시계열 데이터의 특징 ]
- 동일한/ 고정된 간격의 날짜-시간 index (equally spaced time interval, fixed frequency)
- 중복 없고, 빠진 것도 없는 날짜-시간 index (no redundant values or gaps)
- 시간 순서대로 정렬 (sequential order)
(* 시계열 데이터가 반드시 동일한/고정된 간격의 날짜-시간을 가져야만 하는 것은 아님. 가령, 주가(stock price) 데이는 장이 열리는 business day에만 존재하며 공휴일은 데이터 없음)
(1) 동일 간격의 시계열 데이터 Series 만들기 (fixed frequency time series pandas Series) |
(1-1) 중간에 날짜가 비어있는 시계열 데이터 Series 만들기 (non-equally spaced time series)
먼저, 예제로 사용할 간단한 시계열 데이터 pandas Series 를 만들어보겠습니다. 의도적으로 '2019-12-04', '2019-12-08' 일의 날짜-시간 index 를 제거(drop)하여 이빨 빠진 날짜-시간 index 를 만들었습니다.
import pandas as pd # generate dates from 2019-12-01 to 2019-12-10 date_idx = pd.date_range('2019-12-01', periods=10) date_idx
# drop 2 dates from DatetimeIndex date_idx = date_idx.drop(pd.DatetimeIndex(['2019-12-04', '2019-12-08'])) date_idx [Out]: DatetimeIndex(['2019-12-01', '2019-12-02', '2019-12-03', '2019-12-05',
'2019-12-06', '2019-12-07', '2019-12-09', '2019-12-10'],
dtype='datetime64[ns]', freq=None) # Time Series with missing dates index series_ts_missing = pd.Series(range(len(date_idx)) , index=date_idx) series_ts_missing [Out]: 2019-12-01 0
2019-12-02 1
2019-12-03 2
2019-12-05 3
2019-12-06 4
2019-12-07 5
2019-12-09 6
2019-12-10 7
dtype: int64 |
(1-2) 이빨 빠진 Time Series를 동일한 간격의 시계열 데이터 pandas Series로 변환하기
(fixed frequency, equally spaced time interval time series)
위의 (1-1)에서 만든 Series는 '2019-12-04', '2019-12-08'일의 날짜-시간 index가 빠져있는데요, 이럴 경우 resample('D')를 이용하여 날짜-시간 index는 등간격의 날짜-시간을 채워넣고, 대신 값은 결측값 처리(missing value, NaN, Not a Number)를 해보겠습니다.
# Create a 1 day Fixed Frequency Time Series using resample('D') series_ts_fixed_freq = series_ts_missing.resample('D') series_ts_fixed_freq.first() [Out]: 2019-12-01 0.0 2019-12-02 1.0 2019-12-03 2.0 2019-12-04 NaN <--- 2019-12-05 3.0 2019-12-06 4.0 2019-12-07 5.0 2019-12-08 NaN <--- 2019-12-09 6.0 2019-12-10 7.0 Freq: D, dtype: float64 |
비어있던 '날짜-시간' index 를 등간격 '날짜-시간' index로 채우면서 값(value)에 'NaN'이 생긴 부분을 fillna(0)을 이용하여 '0'으로 채워보겠습니다.
# fill missing value with '0' series_ts_fixed_freq.first().fillna(0) [Out]: 2019-12-01 0.0 2019-12-02 1.0 2019-12-03 2.0 2019-12-04 0.0 <--- 2019-12-05 3.0 2019-12-06 4.0 2019-12-07 5.0 2019-12-08 0.0 <--- 2019-12-09 6.0 2019-12-10 7.0 Freq: D, dtype: float64
|
이번에는 resample('10T')를 이용하여 '10분 단위의 동일 간격 날짜-시간' index의 시계열 데이터를 만들어보겠습니다. 이때도 원래의 데이터셋에 없던 '날짜-시간' index의 경우 값(value)은 결측값으로 처리되어 'NaN'으로 채워집니다.
# resampling with 10 minutes frequency (interval) series_ts_missing.resample('10T').first()
|
(2) 동일 간격의 시계열 데이터 DataFrame 만들기 (fixed frequency time series pandas DataFrame) |
(2-1) 중간에 날짜가 비어있는 시계열 데이터 DataFrame 만들기 (non-equally spaced time series DataFrame)
pd.date_range() 함수로 등간격의 10일치 날짜-시간 index를 만든 후에, drop(pd.DatetimeIndex()) 로 '2019-12-04', '2019-12-08'일을 제거하여 '이빨 빠진 날짜-시간' index를 만들었습니다.
import pandas as pd # generate dates from 2019-12-01 to 2019-12-10 date_idx = pd.date_range('2019-12-01', periods=10) # drop 2 dates from DatetimeIndex date_idx = date_idx.drop(pd.DatetimeIndex(['2019-12-04', '2019-12-08'])) date_idx
df_ts_missing = pd.DataFrame(range(len(date_idx)) , columns=['col'] , index=date_idx) df_ts_missing [Out]:
|
(2-2) 이빨 빠진 Time Series를 동일한 간격의 시계열 데이터 pandas DataFrame으로 변환하기
(fixed frequency, equally spaced time interval time series pandas DataFrame)
resample('D') 를 메소드를 사용하여 '일(Day)' 동일 간격의 '날짜-시간' index를 가지는 시계열 데이터 DataFrame을 만들었습니다. 이때 원래의 데이터에 없던 '날짜-시간' index의 경우 결측값 처리되어 값(value)은 'NaN'으로 처리됩니다.
df_ts_fixed_freq = df_ts_missing.resample('D').first() df_ts_fixed_freq [Out]:
|
동일 간견 시계열 데이터로 변환하는 과정에서 생긴 'NaN' 결측값 부분을 fillina(0) 메소드를 이용하여 '0'으로 대체하여 채워보겠습니다.
# fill missing value with '0' df_ts_fixed_freq = df_ts_fixed_freq.fillna(0) df_ts_fixed_freq
|
많은 도움이 되었기를 바랍니다.
이번 포스팅이 도움이 되었다면 아래의 '공감~'를 꾹 눌러주세요. :-)