/ DATA-SCIENCE

Timeseries Analysis1 - datetime 라이브러리

시간정보를 다루는 python 모듈에는 datetime, dateutil 등이 있다. pandas 라이브러리는 시계열 데이터를 다룰 때 내부적으로 이 모듈들을 조합해서 사용한다.

본 포스트에서는 python 환경에서 pnadas로 시계열 분석을 위한 기본 라이브러리에 대해서 살펴본다.

0. Library import

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import datetime
import warnings; warnings.filterwarnings('ignore')
plt.style.use('ggplot')
%matplotlib inline

1. datetime library

날짜정보 객체 만들기. datetime 라이브러리 안에 datetime 메서드를 사용한다.

my_birthday = datetime.datetime(1980, 5, 28)

다음과 같이 라이브러리를 import 하자.

from datetime import datetime
my_birthday = datetime(1980, 5, 28)
my_birthday
datetime.datetime(1980, 5, 28, 0, 0)

데이터 타입을 확인해보자. datetime.datetime 포맷으로 표시된다.

type(my_birthday)
datetime.datetime

현재 날짜와 시간 구하기 1

today = datetime.today()
today
datetime.datetime(2022, 1, 9, 14, 33, 52, 922236)

현재 날짜와 시간 구하기 2

today = datetime.now()
today
datetime.datetime(2022, 1, 9, 14, 33, 53, 834119)
print(today)
2022-01-09 14:33:53.834119

연-월-일 시:분:초 형태로 표현된다.

strftime 메서드 : 날짜정보를 문자열로 리턴한다. 메서드 인자로 문자열 포멧을 지정할 수 있다.
포멧에 대한 자세한 내용은 [이곳]을 참고한다.

today = today.strftime('%Y-%m-%d')
print(today)
2022-01-09
type(today)
str

시간 정보를 가져올 수도 있다.

today = datetime.now()
nowTime = today.strftime('%H:%M:%S')
print(nowTime)
18:39:05

날짜, 시간정보 가져오기.

today = datetime.now()
todayTime = today.strftime('%Y-%m-%d %H:%M:%S')
print(todayTime)
2020-07-19 18:39:05

해당 일의 요일 정보를 가져올 수도 있다.

today = datetime.now()
day = today.strftime('%A')
print(day)
Sunday
day = today.strftime('%a')
print(day)
Sun

strptime 메서드 : 문자열을 datetime 포맷으로 변환한다.

my_birthday = '1980-05-28 14:30:00'
my_birthday = datetime.strptime(my_birthday, '%Y-%m-%d %H:%M:%S')
print(type(my_birthday))
print(my_birthday)
    <class 'datetime.datetime'>
    1980-05-28 14:30:00

날짜, 시간 정보 인덱싱하기

today = datetime.now()
date = today.date()
print(date)
    2022-01-09
nowTime = today.time()
print(nowTime)
14:43:28.290642

날짜, 시간정보 합치기

dateTime = datetime.combine(date, nowTime)
print(dateTime)
2022-01-09 14:43:28.290642

년(year), 월(month), 일(day) 정보를 인덱싱하기

today = datetime.now()
print(today)
2022-01-09 14:43:55.073929
print(today.year)
print(today.month)
print(today.day)
    2022
    1
    9

날짜 연산

from datetime import timedelta
today = datetime.now().date()
print(today)
2022-01-09
tomorrow = today + timedelta(days=1)
print(tomorrow)
2022-01-10

days 대신에 사용할 수 있는 인자 값 : weeks, hours, minutes, seconds 등

dates = [datetime(2022, 1, 9), datetime(2022, 1, 9)+timedelta(days= 1)]
dates
[datetime.datetime(2022, 1, 9, 0, 0), datetime.datetime(2022, 1, 10, 0, 0)]
dates = [datetime(2022, 1, 9), datetime(2022, 1, 9)+timedelta(days= 20)]
dates
[datetime.datetime(2022, 1, 9, 0, 0), datetime.datetime(2022, 1, 29, 0, 0)]

2. numpy의 datetime64

numpy에는 시계열 정보를 정교하게 저장하기 위한 datetime64라는 것이 존재한다.

date = np.array('2022-01-09', dtype=np.datetime64)
date
array('2022-01-09', dtype='datetime64[D]')

datetime 라이브러리와 호환도 가능하다.

np.datetime64(dateTime.now(), 'ns')
numpy.datetime64('2022-01-09T15:09:57.298117000')

날짜 연산도 가능하다.

date + np.arange(20)
    array(['2022-01-09', '2022-01-10', '2022-01-11', '2022-01-12',
           '2022-01-13', '2022-01-14', '2022-01-15', '2022-01-16',
           '2022-01-17', '2022-01-18', '2022-01-19', '2022-01-20',
           '2022-01-21', '2022-01-22', '2022-01-23', '2022-01-24',
           '2022-01-25', '2022-01-26', '2022-01-27', '2022-01-28'],
          dtype='datetime64[D]')

3. pandas built-in 라이브러리

pandas에서는 Timestamp라는 객체를 내부적으로 사용한다. 이 것으로 앞에 소개한 datetime, dateutil, 그리고 numpy의 datetime64를 편하게 조합할 수 있다.

to_datetime : 문자열을 Timestamp 포맷을 변경한다.

today = pd.to_datetime('2022-01-09')
today
    Timestamp('2022-01-09 00:00:00')

날짜 정보 parsing도 가능하다.

my_birthday = pd.to_datetime("28th of May, 1980")
my_birthday
Timestamp('1980-05-28 00:00:00')

DatetimeIndex : DataFrame이나 Series의 인덱스로 사용되는 포맷을 구성한다.

dates = [datetime(2022, 1, 9), datetime(2022, 1, 9)+timedelta(days= 20)]
dt_index = pd.DatetimeIndex(dates)
dt_index
    DatetimeIndex(['2022-01-09', '2022-01-29'], dtype='datetime64[ns]', freq=None)

특정 구간을 DatetimeIndex로 만들려면 시작, 종료지점, 그리고 빈도수를 지정하면 된다.

dt_index = pd.date_range(dates[0], dates[1], freq='D')
dt_index
    DatetimeIndex(['2022-01-09', '2022-01-10', '2022-01-11', '2022-01-12',
                   '2022-01-13', '2022-01-14', '2022-01-15', '2022-01-16',
                   '2022-01-17', '2022-01-18', '2022-01-19', '2022-01-20',
                   '2022-01-21', '2022-01-22', '2022-01-23', '2022-01-24',
                   '2022-01-25', '2022-01-26', '2022-01-27', '2022-01-28',
                   '2022-01-29'],
                  dtype='datetime64[ns]', freq='D')

또 다른 방법

dt_index = dates[0] + pd.to_timedelta(np.arange(21), unit='D')
dt_index
    DatetimeIndex(['2022-01-09', '2022-01-10', '2022-01-11', '2022-01-12',
                   '2022-01-13', '2022-01-14', '2022-01-15', '2022-01-16',
                   '2022-01-17', '2022-01-18', '2022-01-19', '2022-01-20',
                   '2022-01-21', '2022-01-22', '2022-01-23', '2022-01-24',
                   '2022-01-25', '2022-01-26', '2022-01-27', '2022-01-28',
                   '2022-01-29'],
                  dtype='datetime64[ns]', freq=None)

freq 관련 주요 인자는 다음과 같다.

  • s: 초
  • T: 분
  • H: 시간
  • D: 일(day)
  • B: 주말이 아닌 평일
  • W: 주(일요일)
  • W-MON: 주(월요일)
  • M: 각 달(month)의 마지막 날
  • MS: 각 달의 첫날
  • BM: 주말이 아닌 평일 중에서 각 달의 마지막 날
  • BMS: 주말이 아닌 평일 중에서 각 달의 첫날
  • WOM-2THU: 각 달의 두번째 목요일
  • Q-JAN: 각 분기의 첫달의 마지막 날
  • Q-DEC: 각 분기의 마지막 달의 마지막 날

date_range와 유사한 period_range, timedelta_range도 있다.

pd.period_range('2022-01', periods=8, freq='M')
    PeriodIndex(['2022-01', '2022-02', '2022-03', '2022-04', '2022-05', '2022-06',
                 '2022-07', '2022-08'],
                dtype='period[M]', freq='M')
pd.timedelta_range(0, periods=10, freq='H')
    TimedeltaIndex(['0 days 00:00:00', '0 days 01:00:00', '0 days 02:00:00',
                    '0 days 03:00:00', '0 days 04:00:00', '0 days 05:00:00',
                    '0 days 06:00:00', '0 days 07:00:00', '0 days 08:00:00',
                    '0 days 09:00:00'],
                   dtype='timedelta64[ns]', freq='H')
pd.timedelta_range(0, periods=10, freq='1T30S') # 1T30S : 1분 30초
    TimedeltaIndex(['0 days 00:00:00', '0 days 00:01:30', '0 days 00:03:00',
                    '0 days 00:04:30', '0 days 00:06:00', '0 days 00:07:30',
                    '0 days 00:09:00', '0 days 00:10:30', '0 days 00:12:00',
                    '0 days 00:13:30'],
                   dtype='timedelta64[ns]', freq='90S')

4. 시계열 데이터셋 만들기

dates = [datetime(2022, 1, 1), datetime(2022, 1, 1)+timedelta(days= 4)]
dt_index = pd.date_range(dates[0], dates[1], freq='D')

Series 만들기

series = pd.Series(np.random.randn(len(dt_index)), index=dt_index)
series
    2022-01-01   -0.132021
    2022-01-02    1.090681
    2022-01-03   -0.787756
    2022-01-04   -2.461332
    2022-01-05   -0.315497
    Freq: D, dtype: float64

Dataframe 만들기

columns = ['A', 'B', 'C', 'D']
data = np.random.randn(len(dt_index), len(columns))
df = pd.DataFrame(data = data, index=dt_index, columns=columns)
df
A B C D
2022-01-01 0.887873 -1.127382 2.203209 -0.247588
2022-01-02 -0.653866 0.350450 0.089382 -2.678953
2022-01-03 -0.976342 0.032952 0.675049 -0.308314
2022-01-04 1.318794 0.667468 -0.886021 2.705370
2022-01-05 0.302409 -0.712497 0.513426 2.089435

Dataframe 살펴보기

df.index
    DatetimeIndex(['2022-01-01', '2022-01-02', '2022-01-03', '2022-01-04',
                   '2022-01-05'],
                  dtype='datetime64[ns]', freq='D')
df.index.min()
    Timestamp('2022-01-01 00:00:00', freq='D')
df.index.max()
    Timestamp('2022-01-05 00:00:00', freq='D')