[Python.TimeSeries] Date와 DateTime 심화 - Rolling and Shift
2021. 2. 24. 05:00ㆍPython과 머신러닝/TimeSeries & DateTime
0. 이전 포스트
- 2021/02/22 - [Python과 머신러닝/TimeSeries & DateTime] - [Python.TimeSeries] Date와 DateTime
- 2021/02/23 - [Python과 머신러닝/TimeSeries & DateTime] - [Python.TimeSeries] Date와 DateTime 심화 - Resample, Groupby
1. Data Input
In [1]:import pandas as pd
import os
In [2]:df = pd.read_csv('bike_demand_train.csv',
parse_dates=['datetime'])
df.set_index('datetime', inplace=True)
df
Out[2]:
- 시계열 데이터를 분석하다 보면 '지난달의 데이터가 이번 달의 데이터에 어떤 영향을 미쳤는지' 확인해야 하는 경우가 대부분이다.
- 그렇기 때문에 이번 포스트에서는 Rolling과 Shift라는 개념/기능을 통해서 어떻게 데이터를 전 처리할 수 있는지 볼 계획이다.
2. 월별 평균 구하기
In [3]:monthly_mean = df['count'].resample('M').mean()
monthly_mean
Out[3]:datetime
2011-01-31 54.645012
2011-02-28 73.641256
2011-03-31 86.849776
2011-04-30 111.026374
2011-05-31 174.809211
2011-06-30 196.877193
2011-07-31 203.614035
2011-08-31 182.666667
2011-09-30 174.622517
2011-10-31 174.773626
2011-11-30 155.458333
2011-12-31 134.173246
2012-01-31 124.353201
2012-02-29 145.646154
2012-03-31 208.276923
2012-04-30 257.455947
2012-05-31 264.109649
2012-06-30 287.186404
2012-07-31 267.037281
2012-08-31 285.570175
2012-09-30 292.598684
2012-10-31 280.508772
2012-11-30 231.980220
2012-12-31 217.054825
Freq: M, Name: count, dtype: float64
- 우선은 월별 평균을 구해본다.
- 지난 포스트에서 봤던 resample 함수를 통해서 월별 자전거 사용량 데이터를 추출한다.
- 2021/02/23 - [Python과 머신러닝/TimeSeries & DateTime] - [Python.TimeSeries] Date와 DateTime 심화 - Resample, Groupby
3. Shift를 이용해서 월별 데이터를 수정하기
In [4]:monthly_mean_shift = monthly_mean.shift(periods=2, fill_value=0)
monthly_mean_shift
Out[4]:datetime
2011-01-31 0.000000
2011-02-28 0.000000
2011-03-31 54.645012
2011-04-30 73.641256
2011-05-31 86.849776
2011-06-30 111.026374
2011-07-31 174.809211
2011-08-31 196.877193
2011-09-30 203.614035
2011-10-31 182.666667
2011-11-30 174.622517
2011-12-31 174.773626
2012-01-31 155.458333
2012-02-29 134.173246
2012-03-31 124.353201
2012-04-30 145.646154
2012-05-31 208.276923
2012-06-30 257.455947
2012-07-31 264.109649
2012-08-31 287.186404
2012-09-30 267.037281
2012-10-31 285.570175
2012-11-30 292.598684
2012-12-31 280.508772
Freq: M, Name: count, dtype: float64
- monthly_mean.shift(periods=2, fill_value=0)
- 2단계에서 resample을 통해 monthly_mean을 구해서, 월별 데이터를 구했다.
- 이 데이터에 shift를 하는데 2개 단위로 shift를 한다.
- fill_value=0 : 앞에서 2개를 shift 하면 첫 2개는 값이 없을 테니, 0으로 채운다.
- 이렇게 하여 기존의 1월 데이터는 3월에, 2월 데이터는 4월에 등등 이어서 채워지게 된다.
4. 기존 월평균과 shift 월평균 하나의 그래프로 표현하기
In [5]:df_monthly = pd.DataFrame(monthly_mean, columns=['count'])
In [6]:df_monthly['2_shift_demand'] = monthly_mean_shift
df_monthly
In [7]:df_monthly.plot()
- 이 둘을 하나의 df_monthly라는 dataframe에 넣고 plot 하면 위와 같이 결과가 나온다.
- 결국 동일한 데이터를 2개월 단위로 미뤄놓고 봄으로써, 2달 전의 데이터가 현재 데이터에 어떤 영향을 미치는지 시각적으로 볼 수도 있고, 추후에는 Machine Learning에 필요한 데이터로 사용할 수 있다.
5. Moving Average (이동 평균)을 위한 Data 전처리
In [8]:monthly_mean = df['count'].resample('D').mean().fillna(0)
monthly_mean
Out[8]:datetime
2011-01-01 41.041667
2011-01-02 34.826087
2011-01-03 61.318182
2011-01-04 67.913043
2011-01-05 69.565217
...
2012-12-15 210.291667
2012-12-16 157.750000
2012-12-17 191.041667
2012-12-18 231.541667
2012-12-19 219.458333
Freq: D, Name: count, Length: 719, dtype: float64
In [9]:monthly_mean_shift = monthly_mean.rolling(window=30,).mean()
In [10]:df_monthly = pd.DataFrame(monthly_mean, columns=['count'])
df_monthly['30_mean_average'] = monthly_mean_shift
df_monthly.head(31)
Out[10]:
- Moving Average (이동 평균) : 시계열 데이터에는 노이즈가 많기 때문에, 구간을 겹쳐서 평균을 구하고,
- 그 평균들의 추세를 보는 것이 더 정확한 분석이 된다.
- 위 표로 예를 들어 설명하면, 좌측의 count는 기존에도 봤던 일별 count의 평균이다.
- 우측의 30_mean_average는 30일간의 데이터의 평균을 낸 것이다.
- 그래서 2011-01-30의 30_mean_average는 1월 1일부터 30일까지의 평균을 낸 것이고,
- 2011-01-31의 average는 1월 2일부터 31일까지의 평균을 낸 것이다.
- 이렇게 이동 평균을 구하게 되면, 한 데이터의 노이즈가 발생하더라도 추세에 큰 영향을 주지 않아서 분석이 훨씬 용이해지고 정확해진다.
6. 그래프로 표현하기
In [11]:df_monthly.plot(figsize=(20,10))
Out[11]:
- 파란색 선은 일별 평균값이다. 보다시피 중간중간 결측치도 많아서 추세라고 할 것이 없다.
- 그에 비해 30일 이동평균은 결측치와 노이즈를 감안하여 계산되기 때문에 훨씬 더 분석이 용이하고, 유의미한 통찰을 얻을 수 있도록 돕는다.
'Python과 머신러닝 > TimeSeries & DateTime' 카테고리의 다른 글
[Python.TimeSeries] Date와 DateTime 심화 - Resample, Groupby (0) | 2021.02.23 |
---|---|
[Python.TimeSeries] Date와 DateTime (0) | 2021.02.22 |