파이썬 시계열 분석 튜토리얼


시계열(時系列, time series)은 일정한 시간 간격을 바탕으로 입력된 데이터들의 수열을 의미한다. 시계열 데이터는 매출이 존재하는 기업이라면 반드시 존재하기 마련이다. 장기간에 걸쳐 형성된 시계열 데이터를 분석하는 것을 통해 어떤 패턴을 갖는지 알 수 있고 기업이 어떤 특정 기간에 행한 행위의 성과를 평가할 수 있으며(시계열 분석), 더 나아가 기존의 데이터를 바탕으로 미래를 예측할 수도 있다(시계열 예측). 이러한 시계열 분석이 가장 유용히 사용되는 산업 분야는 금융시장, 원유시장, 환율시장 등 미래의 가치를 예측하는 것이 중요한 분야에서 주로 쓰이고 있다.

이번 장에서는 시계열 데이터를 생성하고, 시계열 데이터를 분석하기 위해 가장 널리 사용되는 수학적 모델 ARIMA를 알아본 뒤 미래의 수치를 예측하는 일련의 과정을 알아보고자 한다.

1. 시계열 데이터 생성

시계열 데이터는 그것을 구성하는 인덱스가 날짜 혹은 시간으로 되어 있다. 본 장에서는 시계열 데이터를 다루기 위해 pandas 데이터를 이용하고자 한다. pandas 모듈에서 시계열 자료를 생성하기 위해서는 인덱스를 DatetimeIndex 자료형으로 만들어야 한다. 여기서 DatetimeIndex는 특정 순간에 시간이 기록되는(타임스탬프 형식) 시계열 자료를 다루기 위한 인덱스를 의미한다.

시계열 데이터를 생성하기 위한 모듈에 대해 간략히 알아보았으니 본격적으로 시계열 데이터를 생성해보자. 여기서 시계열 데이터를 생성하기 위해 사용하는 새로운 함수를 알아보자.

예제 (1)

2018년 9월 1일, 5일, 10일, 15일로 구성된 시계열 데이터를 만들고 각 인덱스에 값을 집어 넣어 보자.

In [11]:

import pandas as pd
import numpy as np
date_str =["2018, 9, 1", "2018, 9, 5", "2018, 9, 10","2018, 9, 15"]
idx = pd.to_datetime(date_str)
np.random.seed(0)
s = pd.Series(np.random.randn(4), index = idx)
s

#np.random.seed 를 사용하여 컴퓨터가 임의의 숫자를 알고리즘에 따라 배치하도록 난수를 설정했다.
#np.random.randn 에서 randn()는 임의의 난수를 발생시키는 함수이다. '()' 안에는 발생시키고픈 난수의 갯수를 입력한다.

Out[11]:

2018-09-01    1.764052
2018-09-05    0.400157
2018-09-10    0.978738
2018-09-15    2.240893
dtype: float64
pd.to_datetime
- DatetimeIndex 자료형 인덱스를 생성하는 함수이다.
- 날짜/시간을 나타내는 문자열을 자동적으로 datetime 자료형으로 변환한다.
예제 (1) 해설

09월 1일, 5일, 10일, 15일에 각각의 값이 입력되었다. 9월 5일의 값이 약0.4로 최소치였고 9월 15일의 값이 약2.2로 최대치였다.

우리가 시계열 데이터를 생성할 때, 예제 (1)에서 한 것처럼 일일히 년월일을 입력하는 것은 매우 간단한 일이다. 하지만 우리는 그러한 단순한 작업을 하는 것이 주 목적이 아니므로 더 많은 양의 자료형 데이터를 생성하는 방법에 대해 알아보자.

예제 (2)

2018년 1월 1일부터 1월 31일까지 일단위로 나타나는 DatetimeIndex를 생성해보자

In [13]:

pd.date_range("2018-1-1", "2018-1-31",freq = 'D')
#pd.date_range(start = "2018-1-1", periods=31)

Out[13]:

DatetimeIndex(['2018-01-01', '2018-01-02', '2018-01-03', '2018-01-04',
               '2018-01-05', '2018-01-06', '2018-01-07', '2018-01-08',
               '2018-01-09', '2018-01-10', '2018-01-11', '2018-01-12',
               '2018-01-13', '2018-01-14', '2018-01-15', '2018-01-16',
               '2018-01-17', '2018-01-18', '2018-01-19', '2018-01-20',
               '2018-01-21', '2018-01-22', '2018-01-23', '2018-01-24',
               '2018-01-25', '2018-01-26', '2018-01-27', '2018-01-28',
               '2018-01-29', '2018-01-30', '2018-01-31'],
              dtype='datetime64[ns]', freq='D')
pd.date_range
- 범위 내의 인덱스를 생성하는 함수이다.
- 위의 코드에서 생성한 데이터에 일일히 수작업으로 값을 입력할 필요 없이 
시작일~종료일, 시작일~기간을 작성하면 해당 범위 내에 인덱스를 생성한다.
예제 (2) 해설

2018년 1월 1일부터 2018년 1월 31일까지의 DatetimeIndex가 생성되었다. 제일 하단부의 dtype는 위 데이터의 자료형이 datetime 임을 알려준다. 그 옆의 freq는 특정한 날짜를 생성하도록 하는 인수이다. 빈번히 사용되는 인수의 값들을 아래의 표를 통해 살펴보자.

code세부내용
s
T
H시간
D일(Day)
B평일(Weekday)
W주말(Sunday)
W-Mon매주 월요일
M각 달(Month)의 마지막 날(Day)
BM평일 중에서 각 달의 마지막 날(Day)
BMS평일 중에서 각 달의 첫 날(Day)
Q-JAN각 분기 첫달의 마지막 날(Day)
Q-DEC각 분기 마지막 달의 마지막 날(Day)
응용 예제 (2-1)

예제 (2)에서 생성한 31개의 자료형 데이터에 numpy 모듈의 난수입력 함수를 사용하여 값을 집어넣어 보자.

In [87]:

date_31 = pd.date_range("2018-1-1", "2018-1-31",freq = 'D')
np.random.seed(0)
date_31_seed = pd.Series(np.random.randn(31), index = date_31)
date_31_seed.index.name = "date", "values"
date_31_seed
#index.name을 사용하여 index의 이름을 지정할 수 있다.

Out[87]:

(date, values)
2018-01-01    1.764052
2018-01-02    0.400157
2018-01-03    0.978738
2018-01-04    2.240893
2018-01-05    1.867558
2018-01-06   -0.977278
2018-01-07    0.950088
2018-01-08   -0.151357
2018-01-09   -0.103219
2018-01-10    0.410599
2018-01-11    0.144044
2018-01-12    1.454274
2018-01-13    0.761038
2018-01-14    0.121675
2018-01-15    0.443863
2018-01-16    0.333674
2018-01-17    1.494079
2018-01-18   -0.205158
2018-01-19    0.313068
2018-01-20   -0.854096
2018-01-21   -2.552990
2018-01-22    0.653619
2018-01-23    0.864436
2018-01-24   -0.742165
2018-01-25    2.269755
2018-01-26   -1.454366
2018-01-27    0.045759
2018-01-28   -0.187184
2018-01-29    1.532779
2018-01-30    1.469359
2018-01-31    0.154947
Freq: D, dtype: float64
응용 예제 (2-1) 해설

먼저 2018년 1월 1일부터 1월 31일까지의 DatetimeIndex 데이터를 date_31 이라는 새로운 변수에 집어넣은 뒤, numpy의 seed 함수로 난수를 생성했다. 마무리 작업으로 randn 함수를 사용하여 임의의 값을 date_31의 각각의 인덱스에 삽입했다.

2. 시계열 데이터 분석 & 예측

이번 챕터에서는 시계열을 분석하는 과정과 시계열 분석의 궁극적인 목표라 할 수 있는 시계열 예측에 대해서 알아보자. 시계열 분석은 독립변수로 종속변수를 예측하는 것에 추가적으로 ‘시간’이라는 독립변수를 사용한다는 것이 특징이다. 따라서 일반적인 기계 학습방식과는 다른 분석기법에 대한 고찰이 필요하다.

시계열이라는 개념은 일반적으로 정상 시계열과 비정상 시계열로 구분된다. 정상 시계열은 뚜렷한 추세가 없고 진폭이 시간의 흐름에 따라 일정한 것을 의미한다. 비정상 시계열은 시간대에 따라 데이터의 평균수준이 다르고 추세와 계절성을 가지며 분산이 변한다는 특징을 갖고 있다. 정상 시계열의 경우 전처리 과정에서 특별한 번거로움 없이 기계학습을 통해 분석을 하는 무난한 과정을 거친다. 하지만 비정상 시계열의 경우 그대로 기계학습을 진행할 경우 데이터의 편향성(bias)으로 인해 제대로 된 분석과 예측이 이뤄지지 않는다. 이러한 문제점들을 해결하기 위한 방법으로 본 책에서는 ARIMA 모형이라는 도구를 사용하여 시계열 데이터를 분석 및 예측하고자 한다.

본격적인 분석에 앞서 ARIMA 모형에 대해 알아보자.

ARIMA(AutoRegressive Intergrated Moving Average)

ARIMA는 자기회귀모형(AutoRegressive)과 이동평균모형(Moving Average)가 결합된(Intergrated) 모형을 의미한다. 즉 두가지 모형(AR 과 MA)를 따로 고려하는 것이 아니라 둘 다 고려하는 것이다. 현실 데이터 대부분의 경우 비정상 시계열의 성격을 띈다. 따라서 시계열의 비정상성을 해소하기 위해 관측치간의 차분(Difference)을 사용한다.

여기서 자기회귀모형, 차분과 이동평균모형이라는 개념에 익숙하지 않은 독자들을 위해 간단히 설명하고 넘어가고자 한다.

  • AR(AutoRegressive) : 자기회귀. 이전 관측값이 바로 다음의 관측값에 영향을 주는 것을 의미한다.
  • I(Intergrated) : 병합이라는 의미보다는 누적이라는 의미로 해석하는 것이 적절하다. 차분(Difference)을 이용하는 시계열 모형들에 붙이는 표현이다. 여기서 차분에 대해 간략히 설명하면 우리가 사용하는 수리적 모형들은 거의 다 정상 시계열을 처리하는 것을 기본으로 설계되어 있다. 따라서 우리는 비정상 시계열을 정상 시계열로 만들어줘야 하고 그렇게 하기 위한 방법으로 차분을 사용한다.
  • MA(MovingAverage) : 이동평균. 알고자 하는 관측값이 이전의 연속적인 오차항들의 영향을 받는 것을 의미한다. 주로 추세가 있는 시계열 데이터에서 미래값을 예측하고자 할 때 사용한다.

최종적으로 표현할 때는 ARIMA(p, d, q)라고 한다. 더 자세한 설명을 원하는 경우 “Box, George; Jenkins, Gwilym (1970). Time Series Analysis: Forecasting and Control.” 라는 문헌을 참고하길 바란다.

우리가 사용할 ARIMA 모형에 대해 알아보았으니 본격적으로 분석에 들어가야 한다. 우리가 분석할 데이터는 위에서 생성한 date_31_seed 시계열 데이터이다. 실제 산업현장에서 가져온 데이터를 사용하는 것이 바람직하겠으나 환경적 제약으로 인해 직접 생성한 데이터를 이용하고자 한다.

예제 (3)

우리가 위에서 만든 date_31_seed 시계열 데이터는 2018년 1월 1일부터 31일까지의 기록을 갖고 있다. 필자는 이 데이터를 바탕으로 2018년 2월 1일의 예측값을 구하고자 한다.위에서 설명한 ARIMA 모형을 이용하여 date_31_seed 데이터를 가져온 뒤 현재 기록된 시계열 데이터를 바탕으로 2018년 02월 01일의 수치를 예측해보자.

In [41]:

date_31_seed.plot()
plt.show()

본격적인 분석에 앞서 현재 누적된 시계열 데이터가 어떤 형태로 구성되어 있는지 선 그래프를 이용하여 알아보았다. 뚜렷한 추세는 보이지 않고 불규칙한 형태로 나타나 있다.

다음으로 ARIMA 모형의 모수를 설정하기 위해 ACF, PACF 함수를 사용해보자. ARIMA의 모수를 설정하기 위한 방법으로 우리는 ARIMA(p,d,q)를 사용한다. 보통 모수 설정을 위해AR 모형의 lag를 의미하는 p, MA 모형의 lag를 의미하는 q, 차분 횟수를 의미하는 d를 사용한다. 이 모수의 설정은 임의로 하는 것이 아니라 컴퓨터의 수리적인 도움을 받아야 한다. 우리는 도움을 받기 위해 위에서 언급한 ACF, PACF를 사용한다.

ACF와 PACF라는 개념이 생소한 분들을 위해 잠시 알아보고 진행을 하겠다.

  • ACF(AutoCorrelation Function, 자기상관함수) : Lag에 따른 관측치들 사이의 관련성을 측정하는 함수이다. 즉 과거와 얼마나 강한 정도의 영향을 주고 받고 있는지 알 수 있다.
  • PACF (Partial AutoCorrelation Function, 편자기상관함수) : k 이외의 모든 다른 시점의 관측치가 주는 영향력을 배제하고 해당 관측치와 바로 직전 관측치의 관련성을 측정하는 함수이다. 즉 두 시점간의 공통된 효과를 제거한 뒤 시점간의 상관정도를 알아보는 함수로, AR 모형의 차수를 추정하기 위한 벙법의 하나.

시계열 데이터가 AR(자동회귀)의 특성을 띌 경우 ACF는 서서히 감소하고 PACF는 급속도로 감소한다. 반면 MA(이동평균)의 특성을 띄는 경우 ACF는 급감하고 PACF는 서서히 감소한다. 이 과정에서 급감하는 시차를 AR과 MA 모형의 모수로 사용한다. 이 과정에서 적합한 차분횟수 (d)를 구할 수 있다.

이제부터 분석의 첫 과정을 살펴보자. 먼저 statsmodels모듈에서 pcf와 pacf 함수를 사용하여 ARIMA 모형에 집어넣을 (p,d,q) 를 찾아야 한다.

In [51]:

import matplotlib.pyplot as plt
from statsmodels.graphics.tsaplots import plot_acf, plot_pacf

plot_acf(date_31_seed)
plot_pacf(date_31_seed)
plt.show()

#statsmodels 모듈의 graphics.tsplots에서 acf와 pacf를 사용하기 위해 사용한 코드이다.

차분을 하지 않은 상태에서 date_31_seed의 acf 와 pacf를 그린 결과 k=0을 제외하면 유의미한 자기상관계수, 편자기상관계수의 시차는 보이지 않았다. 따라서 한차례의 차분을 진행하고 다시 진행해보고자 한다.

In [49]:

diff_1 = date_31_seed.diff(periods=1).iloc[1:]
diff_1.plot()
plot_acf(diff_1)
plot_pacf(diff_1)
plt.show()

#diff : 앞의 변수와 그 다음 변수값의 차이를 알고자 할때 사용하는 함수

1회 차분을 진행하고 다시 acf, pacf 함수를 사용하여 그래프를 그린 결과다. 저자는 위의 acf와 pacf를 설명하는 과정에서 “MA(이동평균)의 특성을 띄는 경우 ACF는 급감하고 PACF는 서서히 감소한다. 이 과정에서 급감하는 시차를 AR과 MA 모형의 모수로 사용한다.”라고 라고 언급했다. 상단에 있는 두 그래프를 보면 pacf의 서서히 감소하는 특성이 acf가 가진 특성보다 뚜렷하게 나타났다. 따라서 저자는 이 시계열 데이터 모형의 경우 MA의 특성을 보여주고 있고 이에 맞춰 모수를 설정하기 위해 ARIMA(0,1,1)를 사용했다.

In [31]:

from statsmodels.tsa.arima_model import ARIMA

model = ARIMA(date_31_seed, order=(0,1,1))
model_fit = model.fit(trend = 'c', full_output = True, disp=1)
print(model_fit.summary())

# order(p,d,q) : 왼쪽부터 순서대로 ar, 차분, MA의 매개변수를 입력해야 한다.
# trend : 상수를 포함할지에 대한 여부를 나타낸다. 'c'일 경우 포함하고 'nc'일 경우 포함하지 않음.
# full_output : 모든 출력을 Result 객체의 mle_retvais 속성에서 사용하기 위한 코드인데 필수적인 것은 아님.
# disp = 1 : True면 모든 수렴 정보가 인쇄됨.
                             ARIMA Model Results                              
==============================================================================
Dep. Variable:                    D.y   No. Observations:                   30
Model:                 ARIMA(0, 1, 1)   Log Likelihood                 -45.954
Method:                       css-mle   S.D. of innovations              1.057
Date:                Tue, 02 Oct 2018   AIC                             97.907
Time:                        22:13:15   BIC                            102.111
Sample:                    01-02-2018   HQIC                            99.252
                         - 01-31-2018                                         
==============================================================================
                 coef    std err          z      P>|z|      [0.025      0.975]
------------------------------------------------------------------------------
const         -0.0259      0.021     -1.219      0.233      -0.067       0.016
ma.L1.D.y     -0.9999      0.112     -8.948      0.000      -1.219      -0.781
                                    Roots                                    
=============================================================================
                 Real           Imaginary           Modulus         Frequency
-----------------------------------------------------------------------------
MA.1            1.0001           +0.0000j            1.0001            0.0000
-----------------------------------------------------------------------------
/Users/apple/anaconda3/lib/python3.6/site-packages/statsmodels/tsa/kalmanf/kalmanfilter.py:646: FutureWarning: Conversion of the second argument of issubdtype from `float` to `np.floating` is deprecated. In future, it will be treated as `np.float64 == np.dtype(float).type`.
  if issubdtype(paramsdtype, float):
/Users/apple/anaconda3/lib/python3.6/site-packages/statsmodels/tsa/kalmanf/kalmanfilter.py:650: FutureWarning: Conversion of the second argument of issubdtype from `complex` to `np.complexfloating` is deprecated. In future, it will be treated as `np.complex128 == np.dtype(complex).type`.
  elif issubdtype(paramsdtype, complex):

‘P > |z|’ 값이 학습 모형의 적정성을 확인하기 위해 보여지는 t-test값이다. 즉 0.05 수준의 유의수준으로 보았을 때 현재 0.223으로 유의하지 않음을 알 수 있다. 이러한 문제 상황에 봉착했을 때 우리는 trend의 설정을 ‘nc’로 성정해줌으로써 해결할 수 있다.

코드를 변경하여 다시 진행해보자

In [78]:

model = ARIMA(date_31_seed, order=(0,1,1))
model_fit = model.fit(trend = 'nc', full_output = True, disp=1)
print(model_fit.summary())
                             ARIMA Model Results                              
==============================================================================
Dep. Variable:                    D.y   No. Observations:                   30
Model:                 ARIMA(0, 1, 1)   Log Likelihood                 -46.595
Method:                       css-mle   S.D. of innovations              1.109
Date:                Wed, 03 Oct 2018   AIC                             97.189
Time:                        16:52:08   BIC                             99.992
Sample:                    01-02-2018   HQIC                            98.086
                         - 01-31-2018                                         
==============================================================================
                 coef    std err          z      P>|z|      [0.025      0.975]
------------------------------------------------------------------------------
ma.L1.D.y     -0.9161      0.134     -6.834      0.000      -1.179      -0.653
                                    Roots                                    
=============================================================================
                 Real           Imaginary           Modulus         Frequency
-----------------------------------------------------------------------------
MA.1            1.0915           +0.0000j            1.0915            0.0000
-----------------------------------------------------------------------------
/Users/apple/anaconda3/lib/python3.6/site-packages/statsmodels/tsa/kalmanf/kalmanfilter.py:646: FutureWarning: Conversion of the second argument of issubdtype from `float` to `np.floating` is deprecated. In future, it will be treated as `np.float64 == np.dtype(float).type`.
  if issubdtype(paramsdtype, float):
/Users/apple/anaconda3/lib/python3.6/site-packages/statsmodels/tsa/kalmanf/kalmanfilter.py:650: FutureWarning: Conversion of the second argument of issubdtype from `complex` to `np.complexfloating` is deprecated. In future, it will be treated as `np.complex128 == np.dtype(complex).type`.
  elif issubdtype(paramsdtype, complex):

다시 진행해본 결과 ‘P > |z|’를 확인하니 아주 유의하다고 볼 수 있다. 다음으로 적용시킨 모델이 어떻게 미래의 데이터를 예측했는지 그래프로 먼저 확인해 보자

In [33]:

model_fit.plot_predict()
/Users/apple/anaconda3/lib/python3.6/site-packages/statsmodels/tsa/kalmanf/kalmanfilter.py:577: FutureWarning: Conversion of the second argument of issubdtype from `float` to `np.floating` is deprecated. In future, it will be treated as `np.float64 == np.dtype(float).type`.
  if issubdtype(paramsdtype, float):

Out[33]:

그래프의 파란선이 예측값들의 움직임을 보여준다. 기존 시계열 데이터에서 차분을 진행하여 예측하기 때문에 그래프의 움직임이 기존 데이터와 일치하게 움직이지 않고 있는 것을 볼 수 있다.

다음은 어떤 값을 예측했는지 알아보자

In [34]:

fore = model_fit.forecast(steps = 1)
print(fore)

#forecast : 값을 예측하도록 하는 함수이며 뒤의 steps에는 예측할 개수를 명시해야 한다.
(array([0.36670319]), array([1.10939594]), array([[-1.8076729 ,  2.54107927]]))
/Users/apple/anaconda3/lib/python3.6/site-packages/statsmodels/tsa/kalmanf/kalmanfilter.py:577: FutureWarning: Conversion of the second argument of issubdtype from `float` to `np.floating` is deprecated. In future, it will be treated as `np.float64 == np.dtype(float).type`.
  if issubdtype(paramsdtype, float):

첫 번째 array를 확인하면 된다. 값은 0.36670319가 나왔는데 약 0.37로 부르기로 하자. 다음 진행할 것은 실제 2018년 02월 01일의 값과 우리가 ARIMA모형을 통해 예측한 값을 비교하는 것이다. 두 가지 값이 비슷할 경우 예측을 적절하게 한 것이고 만약 차이가 난다면 적절하지 않은 예측을 한 것이라고 볼 수 있다.

기존의 31개의 데이터에서 1개를 더 추가하여 총 32개의 시계열 데이터를 생성했다. 난수 설정을 동일하기 때문에 기존 데이터들은 동일하며 맨 밑에 2018년 02월 01의 데이터가 추가된 것을 볼 수 있다.

In [35]:

date_32 = pd.date_range("2018-1-1", "2018-2-1",freq = 'D')
np.random.seed(0)
date_32_seed = pd.Series(np.random.randn(32), index = date_32)
columns = ["Date", "values"]
date_32_seed

Out[35]:

2018-01-01    1.764052
2018-01-02    0.400157
2018-01-03    0.978738
2018-01-04    2.240893
2018-01-05    1.867558
2018-01-06   -0.977278
2018-01-07    0.950088
2018-01-08   -0.151357
2018-01-09   -0.103219
2018-01-10    0.410599
2018-01-11    0.144044
2018-01-12    1.454274
2018-01-13    0.761038
2018-01-14    0.121675
2018-01-15    0.443863
2018-01-16    0.333674
2018-01-17    1.494079
2018-01-18   -0.205158
2018-01-19    0.313068
2018-01-20   -0.854096
2018-01-21   -2.552990
2018-01-22    0.653619
2018-01-23    0.864436
2018-01-24   -0.742165
2018-01-25    2.269755
2018-01-26   -1.454366
2018-01-27    0.045759
2018-01-28   -0.187184
2018-01-29    1.532779
2018-01-30    1.469359
2018-01-31    0.154947
2018-02-01    0.378163
Freq: D, dtype: float64

예제 (3) 해설

실제 컴퓨터가 난수를 부여한 2018년 02월 01일의 값은 0.378163이다. 우리가 예측한 값은 0.36670319로 두 값의 차이는 약 0.01정도였다. 이를 통해 ARIMA 모형을 통해 진행한 시계열 예측이 어느정도 유의함을 알 수 있다.

In [83]:

date_32 = pd.date_range("2018-1-1", "2018-2-1",freq = 'D')
np.random.seed(0)
date_32_seed = pd.Series(np.random.randn(32), index = date_32)
columns = ["Date", "values"]
date_32_seed

Out[83]:

2018-01-01    1.764052
2018-01-02    0.400157
2018-01-03    0.978738
2018-01-04    2.240893
2018-01-05    1.867558
2018-01-06   -0.977278
2018-01-07    0.950088
2018-01-08   -0.151357
2018-01-09   -0.103219
2018-01-10    0.410599
2018-01-11    0.144044
2018-01-12    1.454274
2018-01-13    0.761038
2018-01-14    0.121675
2018-01-15    0.443863
2018-01-16    0.333674
2018-01-17    1.494079
2018-01-18   -0.205158
2018-01-19    0.313068
2018-01-20   -0.854096
2018-01-21   -2.552990
2018-01-22    0.653619
2018-01-23    0.864436
2018-01-24   -0.742165
2018-01-25    2.269755
2018-01-26   -1.454366
2018-01-27    0.045759
2018-01-28   -0.187184
2018-01-29    1.532779
2018-01-30    1.469359
2018-01-31    0.154947
2018-02-01    0.378163
Freq: D, dtype: float64
error: Content is protected !!
Scroll to Top