시계열 데이터는 금융, 경제, 생태학, 물리학 등 여러 분야에서 사용되는 매우 중요한 구조화된 데이터이다.
시간상의 여러 지점을 관측하거나 측정할 수 있는 모든 것이 시계열이다.
-시간 내에서 특정 순간의 타임 스탬프
-2018년 9월이나 2017년 같은 고정된 시간
-시작과 끝이 타임 스탬프로 표시되는 시간 간격
-실험 혹은 경과시간
파이썬 표준 라이브러리에는 날짜와 시간 제어를 위한 datetime, time, calendar를 제공해준다.
date : 그레고리언 달력을 사용해서 날짜(년,월,일)을 저장한다.
time : 하루 중 시간을 시간, 분, 초, 마이크로초 단위로 저장한다.
datetime : 날짜와 시간을 같이 저장한다.
timedelta : 두 datetime 값 간의 차이(일,초,마이크로초)를 표현한다.
datetime 객체는 str 메서드나 strftime 메서드에 포맷 규칙을 넘겨 문자열로 나타낼 수 있다.
%Y : 네 자리 연도
%y : 두 자리 연도
%m : 두 자리 월 [01,12]
%d : 두 자리 일 [01,31]
%H : 24시 형식 시간 [00,23]
%I : 12시 형식 시간 [01,12]
%M : 두 자리 분 [00,59]
%S : 초
%w : 정수로 나타낸 요일 [0(일요일),6]
%f : %Y-%m-%d 형식에 대한 축약
from datetime import datetime
now = datetime.now()
print(now)
print('{}년 {}월 {}일'.format(now.year,now.month,now.day))
time1 = datetime(2015,2,22,10,20)
print(time1)
print(time1.strftime('%Y년도-%m월-%d일'))
print()
timestr = '2020-01-07'
time2 = datetime.strptime(timestr, '%Y-%m-%d')
print(time2)
from dateutil.parser import parse
print()
print(parse('2020-01-07'))
print(parse('Jan 31, 2020 10:45 PM'))
2025-03-05 16:40:04.292500
2025년 3월 5일
2015-02-22 10:20:00
2015년도-02월-22일
2020-01-07 00:00:00
2020-01-07 00:00:00
2020-01-31 22:45:00
Pandas 에서 찾아 볼 수 있는 가장 기본적인 시계열의 종류는 파이썬 문자열이나 datetime 객체로 표현되는 타임스탬프로 색인된 Series 객체다
TimeSeries 는 Series의 하위 클래스이므로 라벨에 기반해 데이터를 선택하고 인덱싱 하는데 있어서는 Series와 동일하게 동작한다.
from datetime import datetime
import pandas as pd
import numpy as np
np.random.seed(12345)
dates = [datetime(2024, 1, 1),datetime(2024, 1, 2),datetime(2024, 1, 3),
datetime(2024, 1, 4),datetime(2024, 1, 5),datetime(2024, 1, 6),
datetime(2024, 1, 7),datetime(2024, 1, 8)]
ts = pd.Series(np.random.randn(8), index=dates)
print(ts)
print()
print(ts['2024-01-03'])
print(ts['2024/01/03'])
print(ts['20240103'])
print(ts['01/03/2024'])
print(ts['01-03-2024'])
2024-01-01 -0.204708
2024-01-02 0.478943
2024-01-03 -0.519439
2024-01-04 -0.555730
2024-01-05 1.965781
2024-01-06 1.393406
2024-01-07 0.092908
2024-01-08 0.281746
dtype: float64
-0.5194387150567381
-0.5194387150567381
-0.5194387150567381
-0.5194387150567381
-0.5194387150567381
Pandas 에서 일반적인 시계열은 불규칙적인 것으로 간주한다. 즉 고정된 빈도를 갖
지 않는다. 이를 위해 pandas는 리샘플링, 표준 시계열 빈도 모음, 빈도 추론, 그리
고 고정된 빈도의 날짜 범위를 위한 도구가 있다.
Pandas.date_range()
from datetime import datetime
import pandas as pd
import numpy as np
np.random.seed(12345)
ts2 = pd.Series(np.random.randn(1000),
index=pd.date_range('1/1/2020',periods=1000))
print(ts2)
print()
print(ts2['2021'])
print()
print(ts2['2022-05'])
print(ts2['2022-05-01':'2022-05-10'])
print()
df1 = pd.DataFrame(np.random.randn(100,4),
index=pd.date_range('2020/1/1',periods=100,freq='W-WED'),
columns=['one','two','three','four'])
print(df1)
print()
print(pd.date_range(start='4/1/2020', end='6/1/2020'))
print(pd.date_range(end='6/1/2020',periods=20))
print(pd.date_range('1/1/2010','1/3/2010',freq='4h'))
print(pd.date_range('1/1/2020','1/3/2010',freq='1h30min'))
print(pd.date_range('1/1/2000','2/1/2000',freq='B'))
print(pd.date_range('1/1/2000','12/1/2000',freq='BME'))
2020-01-01 -0.204708
2020-01-02 0.478943
2020-01-03 -0.519439
2020-01-04 -0.555730
2020-01-05 1.965781
...
2022-09-22 0.107657
2022-09-23 -0.139298
2022-09-24 -1.159926
2022-09-25 0.618965
2022-09-26 1.373890
Freq: D, Length: 1000, dtype: float64
2021-01-01 -1.610841
2021-01-02 -1.026621
2021-01-03 1.241573
2021-01-04 -0.156760
2021-01-05 -2.449096
...
2021-12-27 1.578948
2021-12-28 0.000369
2021-12-29 0.900885
2021-12-30 -0.454869
2021-12-31 -0.864547
Freq: D, Length: 365, dtype: float64
2022-05-01 0.003193
2022-05-02 -2.595012
2022-05-03 -1.555569
2022-05-04 1.102996
2022-05-05 0.554737
2022-05-06 -1.289012
2022-05-07 0.385242
2022-05-08 -1.717292
2022-05-09 -1.018353
2022-05-10 0.051635
2022-05-11 0.503299
2022-05-12 -0.543186
2022-05-13 -0.506678
2022-05-14 0.729653
2022-05-15 0.434273
2022-05-16 -1.133674
2022-05-17 1.423953
2022-05-18 0.266352
2022-05-19 -0.854264
2022-05-20 -0.550597
2022-05-21 -0.619110
2022-05-22 1.038933
2022-05-23 -0.910611
2022-05-24 0.529953
2022-05-25 -0.008471
2022-05-26 -1.129038
2022-05-27 0.569854
2022-05-28 -0.863392
2022-05-29 -1.356144
2022-05-30 -0.057152
2022-05-31 -0.108621
Freq: D, dtype: float64
2022-05-01 0.003193
2022-05-02 -2.595012
2022-05-03 -1.555569
2022-05-04 1.102996
2022-05-05 0.554737
2022-05-06 -1.289012
2022-05-07 0.385242
2022-05-08 -1.717292
2022-05-09 -1.018353
2022-05-10 0.051635
Freq: D, dtype: float64
one two three four
2020-01-01 -0.983505 0.930944 -0.811676 -1.830156
2020-01-08 -0.138730 0.334088 0.488675 -0.178098
2020-01-15 2.122315 0.061192 0.884111 -0.608506
2020-01-22 -0.072052 0.544066 0.323886 -1.683325
2020-01-29 0.526860 1.858791 -0.548419 -0.279397
... ... ... ... ...
2021-10-27 0.370548 -0.674167 -1.712340 -0.738151
2021-11-03 0.391813 1.763403 -0.054630 -0.656506
2021-11-10 -1.550087 -0.044347 0.681470 -0.953726
2021-11-17 -1.857016 0.449495 -0.061732 1.233914
2021-11-24 0.705830 -1.309077 -1.537380 0.531551
[100 rows x 4 columns]
DatetimeIndex(['2020-04-01', '2020-04-02', '2020-04-03', '2020-04-04',
'2020-04-05', '2020-04-06', '2020-04-07', '2020-04-08',
'2020-04-09', '2020-04-10', '2020-04-11', '2020-04-12',
'2020-04-13', '2020-04-14', '2020-04-15', '2020-04-16',
'2020-04-17', '2020-04-18', '2020-04-19', '2020-04-20',
'2020-04-21', '2020-04-22', '2020-04-23', '2020-04-24',
'2020-04-25', '2020-04-26', '2020-04-27', '2020-04-28',
'2020-04-29', '2020-04-30', '2020-05-01', '2020-05-02',
'2020-05-03', '2020-05-04', '2020-05-05', '2020-05-06',
'2020-05-07', '2020-05-08', '2020-05-09', '2020-05-10',
'2020-05-11', '2020-05-12', '2020-05-13', '2020-05-14',
'2020-05-15', '2020-05-16', '2020-05-17', '2020-05-18',
'2020-05-19', '2020-05-20', '2020-05-21', '2020-05-22',
'2020-05-23', '2020-05-24', '2020-05-25', '2020-05-26',
'2020-05-27', '2020-05-28', '2020-05-29', '2020-05-30',
'2020-05-31', '2020-06-01'],
dtype='datetime64[ns]', freq='D')
DatetimeIndex(['2020-05-13', '2020-05-14', '2020-05-15', '2020-05-16',
'2020-05-17', '2020-05-18', '2020-05-19', '2020-05-20',
'2020-05-21', '2020-05-22', '2020-05-23', '2020-05-24',
'2020-05-25', '2020-05-26', '2020-05-27', '2020-05-28',
'2020-05-29', '2020-05-30', '2020-05-31', '2020-06-01'],
dtype='datetime64[ns]', freq='D')
DatetimeIndex(['2010-01-01 00:00:00', '2010-01-01 04:00:00',
'2010-01-01 08:00:00', '2010-01-01 12:00:00',
'2010-01-01 16:00:00', '2010-01-01 20:00:00',
'2010-01-02 00:00:00', '2010-01-02 04:00:00',
'2010-01-02 08:00:00', '2010-01-02 12:00:00',
'2010-01-02 16:00:00', '2010-01-02 20:00:00',
'2010-01-03 00:00:00'],
dtype='datetime64[ns]', freq='4h')
DatetimeIndex(['2010-01-01 00:00:00', '2010-01-01 01:30:00',
'2010-01-01 03:00:00', '2010-01-01 04:30:00',
'2010-01-01 06:00:00', '2010-01-01 07:30:00',
'2010-01-01 09:00:00', '2010-01-01 10:30:00',
'2010-01-01 12:00:00', '2010-01-01 13:30:00',
'2010-01-01 15:00:00', '2010-01-01 16:30:00',
'2010-01-01 18:00:00', '2010-01-01 19:30:00',
'2010-01-01 21:00:00', '2010-01-01 22:30:00',
'2010-01-02 00:00:00', '2010-01-02 01:30:00',
'2010-01-02 03:00:00', '2010-01-02 04:30:00',
'2010-01-02 06:00:00', '2010-01-02 07:30:00',
'2010-01-02 09:00:00', '2010-01-02 10:30:00',
'2010-01-02 12:00:00', '2010-01-02 13:30:00',
'2010-01-02 15:00:00', '2010-01-02 16:30:00',
'2010-01-02 18:00:00', '2010-01-02 19:30:00',
'2010-01-02 21:00:00', '2010-01-02 22:30:00',
'2010-01-03 00:00:00'],
dtype='datetime64[ns]', freq='90min')
DatetimeIndex(['2000-01-03', '2000-01-04', '2000-01-05', '2000-01-06',
'2000-01-07', '2000-01-10', '2000-01-11', '2000-01-12',
'2000-01-13', '2000-01-14', '2000-01-17', '2000-01-18',
'2000-01-19', '2000-01-20', '2000-01-21', '2000-01-24',
'2000-01-25', '2000-01-26', '2000-01-27', '2000-01-28',
'2000-01-31', '2000-02-01'],
dtype='datetime64[ns]', freq='B')
DatetimeIndex(['2000-01-31', '2000-02-29', '2000-03-31', '2000-04-28',
'2000-05-31', '2000-06-30', '2000-07-31', '2000-08-31',
'2000-09-29', '2000-10-31', '2000-11-30'],
dtype='datetime64[ns]', freq='BME')
Pandas에서 빈도는 기본 빈도와 배수의 조합으로 이루어진다.
시간 빈도는 Hour 클래스를 사용하여 표현할 수 있다.
시프트는 데이터를 시간 축에서 앞이나 뒤로 이동하는 것을 말한다.
shift 메서드는 이 기능을 제공한다.
몇일, 몇 개월, 몇 분기, 몇 해 같은 기간은 period 클래스로 표현 할 수 있으며 문자열이나 정수 그리고 표의 빈도를 가지고 생성한다.
기간과 periodIndex 객체는 asfreq 메서드를 통해 다른 빈도로도 변환 할 수 있다.
분기 데이터는 재정, 금융 및 다른 분야에서 표준으로 사용된다.
Pandas 는 12 가지 모든 경우의 수를 지원하면 분기 빈도는 Q-Jan부터 Q-DEC 까지다
타임스탬프로 색인된 Series와 DataFrame 객체는 to_period 메서드를 사용해서 Period로 변환할 수 있다.
리샘플링은 시게열의 빈도를 변환하는 과정을 말한다. 상위 빈도의 데이터를 하위 빈도로 집계 하는 것을 다운 샘플링이라고 하면 반대의 과정을 업 샘플링이라고 한다.
Pandas.resample()
freq : 원하는 리샘플링 빈도를 가리키는 문자열이나 DataOffset
how='mean' : 'mean','np.max'같은 집계된 값을 생성하는 함수나 함수의 배열
axis=0 : 리샘플링을 수행할 축
fill_method=None : 업샘플링 시에 사용할 보간 방법.
closed='right' : 다운샘플링 시에 각 간격의 어느 쪽을 포함할지를 가리킨다.
label='right' : 다운샘플링 시에 집계된 결과의 라벨을 결정한다.
limit=None : 보간법 사용 시 보간을 적용할 최대 기간이다.
kind = None : 기간('period')별 혹은 타임스탬프별로 집계할 것인지 구분
convention=None : 기간을 리 샘플링할 때 하위 빈도 기간에서 상위 빈도로 변환할 때의 방식
import pandas as pd
import numpy as np
np.random.seed(12345)
date = pd.date_range('1/1/2020',periods=100,freq='D')
ts = pd.Series(np.random.randn(100), index=date)
print(ts)
print()
rsdata = ts.resample('ME')
print(rsdata)
print()
for data in rsdata:
print(data, end='\n\n')
print()
print(rsdata.mean())
print()
frame= pd.DataFrame(np.random.randn(2,4),
index=pd.date_range('1/1/2020',periods=2,freq='W-WED'),
columns=['one','two','three','four'])
print(frame)
print()
rsdata2 = frame.resample('D')
for data in rsdata2:
print(data, end='\n\n')
print()
print(frame.resample('D').ffill())
print()
print(frame.resample('D').ffill(limit=2))
2020-01-01 -0.204708
2020-01-02 0.478943
2020-01-03 -0.519439
2020-01-04 -0.555730
2020-01-05 1.965781
...
2020-04-05 0.795253
2020-04-06 0.118110
2020-04-07 -0.748532
2020-04-08 0.584970
2020-04-09 0.152677
Freq: D, Length: 100, dtype: float64
DatetimeIndexResampler [freq=<MonthEnd>, axis=0, closed=right, label=right, convention=start, origin=start_day]
(Timestamp('2020-01-31 00:00:00'), 2020-01-01 -0.204708
2020-01-02 0.478943
2020-01-03 -0.519439
2020-01-04 -0.555730
2020-01-05 1.965781
2020-01-06 1.393406
2020-01-07 0.092908
2020-01-08 0.281746
2020-01-09 0.769023
2020-01-10 1.246435
2020-01-11 1.007189
2020-01-12 -1.296221
2020-01-13 0.274992
2020-01-14 0.228913
2020-01-15 1.352917
2020-01-16 0.886429
2020-01-17 -2.001637
2020-01-18 -0.371843
2020-01-19 1.669025
2020-01-20 -0.438570
2020-01-21 -0.539741
2020-01-22 0.476985
2020-01-23 3.248944
2020-01-24 -1.021228
2020-01-25 -0.577087
2020-01-26 0.124121
2020-01-27 0.302614
2020-01-28 0.523772
2020-01-29 0.000940
2020-01-30 1.343810
2020-01-31 -0.713544
Freq: D, dtype: float64)
(Timestamp('2020-02-29 00:00:00'), 2020-02-01 -0.831154
2020-02-02 -2.370232
2020-02-03 -1.860761
2020-02-04 -0.860757
2020-02-05 0.560145
2020-02-06 -1.265934
2020-02-07 0.119827
2020-02-08 -1.063512
2020-02-09 0.332883
2020-02-10 -2.359419
2020-02-11 -0.199543
2020-02-12 -1.541996
2020-02-13 -0.970736
2020-02-14 -1.307030
2020-02-15 0.286350
2020-02-16 0.377984
2020-02-17 -0.753887
2020-02-18 0.331286
2020-02-19 1.349742
2020-02-20 0.069877
2020-02-21 0.246674
2020-02-22 -0.011862
2020-02-23 1.004812
2020-02-24 1.327195
2020-02-25 -0.919262
2020-02-26 -1.549106
2020-02-27 0.022185
2020-02-28 0.758363
2020-02-29 -0.660524
Freq: D, dtype: float64)
(Timestamp('2020-03-31 00:00:00'), 2020-03-01 0.862580
2020-03-02 -0.010032
2020-03-03 0.050009
2020-03-04 0.670216
2020-03-05 0.852965
2020-03-06 -0.955869
2020-03-07 -0.023493
2020-03-08 -2.304234
2020-03-09 -0.652469
2020-03-10 -1.218302
2020-03-11 -1.332610
2020-03-12 1.074623
2020-03-13 0.723642
2020-03-14 0.690002
2020-03-15 1.001543
2020-03-16 -0.503087
2020-03-17 -0.622274
2020-03-18 -0.921169
2020-03-19 -0.726213
2020-03-20 0.222896
2020-03-21 0.051316
2020-03-22 -1.157719
2020-03-23 0.816707
2020-03-24 0.433610
2020-03-25 1.010737
2020-03-26 1.824875
2020-03-27 -0.997518
2020-03-28 0.850591
2020-03-29 -0.131578
2020-03-30 0.912414
2020-03-31 0.188211
Freq: D, dtype: float64)
(Timestamp('2020-04-30 00:00:00'), 2020-04-01 2.169461
2020-04-02 -0.114928
2020-04-03 2.003697
2020-04-04 0.029610
2020-04-05 0.795253
2020-04-06 0.118110
2020-04-07 -0.748532
2020-04-08 0.584970
2020-04-09 0.152677
Freq: D, dtype: float64)
2020-01-31 0.304166
2020-02-29 -0.404772
2020-03-31 0.021947
2020-04-30 0.554480
Freq: ME, dtype: float64
one two three four
2020-01-01 -1.565657 -0.562540 -0.032664 -0.929006
2020-01-08 -0.482573 -0.036264 1.095390 0.980928
(Timestamp('2020-01-01 00:00:00'), one two three four
2020-01-01 -1.565657 -0.56254 -0.032664 -0.929006)
(Timestamp('2020-01-02 00:00:00'), Empty DataFrame
Columns: [one, two, three, four]
Index: [])
(Timestamp('2020-01-03 00:00:00'), Empty DataFrame
Columns: [one, two, three, four]
Index: [])
(Timestamp('2020-01-04 00:00:00'), Empty DataFrame
Columns: [one, two, three, four]
Index: [])
(Timestamp('2020-01-05 00:00:00'), Empty DataFrame
Columns: [one, two, three, four]
Index: [])
(Timestamp('2020-01-06 00:00:00'), Empty DataFrame
Columns: [one, two, three, four]
Index: [])
(Timestamp('2020-01-07 00:00:00'), Empty DataFrame
Columns: [one, two, three, four]
Index: [])
(Timestamp('2020-01-08 00:00:00'), one two three four
2020-01-08 -0.482573 -0.036264 1.09539 0.980928)
one two three four
2020-01-01 -1.565657 -0.562540 -0.032664 -0.929006
2020-01-02 -1.565657 -0.562540 -0.032664 -0.929006
2020-01-03 -1.565657 -0.562540 -0.032664 -0.929006
2020-01-04 -1.565657 -0.562540 -0.032664 -0.929006
2020-01-05 -1.565657 -0.562540 -0.032664 -0.929006
2020-01-06 -1.565657 -0.562540 -0.032664 -0.929006
2020-01-07 -1.565657 -0.562540 -0.032664 -0.929006
2020-01-08 -0.482573 -0.036264 1.095390 0.980928
one two three four
2020-01-01 -1.565657 -0.562540 -0.032664 -0.929006
2020-01-02 -1.565657 -0.562540 -0.032664 -0.929006
2020-01-03 -1.565657 -0.562540 -0.032664 -0.929006
2020-01-04 NaN NaN NaN NaN
2020-01-05 NaN NaN NaN NaN
2020-01-06 NaN NaN NaN NaN
2020-01-07 NaN NaN NaN NaN
2020-01-08 -0.482573 -0.036264 1.095390 0.980928
Resample()을 사용해서 데이터를 다운샘플링할 때 고려해야 할 사항
-각 간격의 양 끝 중에서 열어둘 쪽
-집계하려는 구간의 라벨을 간격의 시작으로 할지 끝으로 할지의 여부