Prev Contents/Wrangling

[파이썬 라이브러리를 활용한 데이터 분석] 17~20일차 (423~479p)

Convergence Medicine 2022. 6. 30. 09:54

11. 시계열

17~20일차 (2020-06-27~30)도 이 책으로 시작:

http://www.kyobobook.co.kr/product/detailViewKor.laf?ejkGb=KOR&mallGb=KOR&barcode=9791162241905&orderClick=LEa&Kc=

 

파이썬 라이브러리를 활용한 데이터 분석 - 교보문고

영화 평점, 이름통계, 선거 데이터 등 실사례 사용 | ★ 『파이썬 라이브러리를 활용한 데이터 분석』 드디어 개정!이 책의 초판이 출간된 2012년은 pandas 개발 초기로, 파이썬용 오픈소스 데이터

www.kyobobook.co.kr

아래의 요약은 책을 충실히 요약한 것이 아닌 오늘 공부한 것의 정리일 뿐입니다.
저자의 코드 예제 github repository: http://github.com/wesm/pydata-book
자세한 내용 책을 사서 보시거나 영문판의 경우 저자의 홈페이지에 3판의 open edition이 있습니다 (https://wesmckinney.com/book/).

 

GitHub - wesm/pydata-book: Materials and IPython notebooks for "Python for Data Analysis" by Wes McKinney, published by O'Reilly

Materials and IPython notebooks for "Python for Data Analysis" by Wes McKinney, published by O'Reilly Media - GitHub - wesm/pydata-book: Materials and IPython notebooks for "Pyth...

github.com

 

Python for Data Analysis, 3E

About the Open Edition The upcoming 3rd edition of Python for Data Analysis is available as an “Open Access” HTML version on this site https://wesmckinney.com/book in addition to the usual print and e-book formats. This is currently an Early Release ve

wesmckinney.com

독자에게 전하는 조언:

1) 데이터 분석을 생산적으로 하기 위해 파이썬으로 훌륭한 소프트웨어를 개발할 수 있을 정도로 파이썬 고수가 되어야 할 필요는 없다고 생각한다.
2) Numpy의 깊은 이해가 필수 사항은 아니며, 배열 위주의 프로그래밍과 생각하는 방법에 능숙해지는 것이 과학 계산의 고수가 되는 지름길이다.

들어가며

  • 시간 내에서 특정 순간의 타임스탬프
  • 고정된 기간
  • 시작과 끝 타임스탬프로 표시되는 시간 간격

을 주로 다루며,

  • 실험 혹은 경과 시간 - pandas 공식 문서를 참조하라

금융, 경제 관련 애플리케이션에 유용하지만 서버 로그 데이터를 분석하는 데에도 사용할 수 있다.

11.1 날짜, 시간 자료형, 도구

from datetime import datetime
datetime.datetime()  # 날짜와 시간을 저장
datetime.timedelta()  # 두 datetime 객체 간의 시간적인 차이를 표현

Refer 표 11-1 datetime 모듈의 자료형

11.1.1 문자열을 datetime으로 변환하기

datetime, pandas의 Timestamp 객체를 문자열로 나타낼 수 있다. - str, strftime(포맷 규칙) 메서드
datetime.strptime() - 반대로 문자열을 날짜로 변환
하지만, 매번 날짜 규칙의 포맷을 전달하여 넘기기 귀찮으므로,
dateutil 모듈의 parser.parse() 메서드를 사용하면 거의 대부분의 인지 가능한 날짜 표현 방식을 파싱하는 것이 가능
날짜가 맨 앞에 오는 경우 dayfirst=True를 인자로 전달하면 된다.
pandas의 to_datetime() 메서드는 많은 종류의 날짜 표현을 처리할 수 있다.
누락된 값 (NaT - Not a Time)도 NA로 처리할 수 있다.
datetime 객체는 여러 나라 혹은 언어에서 사용하는 로케일에 맞는 다양한 포맷 옵션을 제공한다.

Refer 표 11-2 datetime 포맷 규칙 (표 2-5와 동일)
Refer 표 11-3 로케일별 날짜 포맷

11.2 시계열 기초

datetime 객체를 index로 전달하여 Series를 생성, 이들 datetime 객체는 DatetimeIndex에 들어 있으며, 변수의 타입은 TimeSeries이다.
Numpy의 datetime64 자료형을 사용해서 타임스탬프를 저장한다.
DatetimeIndex의 스칼라 값은 pandas의 Timestamp 객체이다.
Timestamp 객체는 datetime 객체를 사용하는 어떤 곳에서도 대체 사용이 가능하며, 빈도에 관한 정보를 저장, 조작을 하는 방법도 포함하고 있다.

11.2.1 색인, 선택, 부분 선택

pd.Series와 동일하게 동작
해석할 수 있는 날짜를 문자열로 넘겨서 편리하게 사용 가능
년 혹은 년, 월만 넘겨서 데이터의 일부 구간만 선택 가능
그러므로, 날짜 문자열, datetime, 타임스탬프를 넘길 수 있다.
뷰를 생성하므로 슬라이스에 대한 변경이 원본 데이터에도 반영됨
truncate() 메서드 - after= 인자에 날짜의 문자열을 전달하여 TimeSeries를 두 개의 날짜로 나눈다.
년 혹은 년, 월만 넘겨서 필터링하는 방법은 DataFrame에도 적용되며 로우에 인덱싱된다.

11.2.2 중복된 색인을 갖는 시계열

여러 데이터가 특정 타임스탬프에 몰려 있는 경우
is_unique 속성으로 색인이 유일하지 않음을 확인
중복 여부에 따라 스칼라값이나 슬라이스가 생긴다.
groupby()level=0 (단일 단계 인덱싱)을 전달하면 중복 아닌 것처럼 집계 가능하다.

11.3 날짜 범위, 빈도, 이동

pandas에서는 리샘플링, 표준 시계열 빈도 모음, 빈도 추론, 고정된 빈도의 날짜 범위를 위한 도구를 제공하고 있다.
예를 들어, resample() 메서드에 문자열 D를 전달하면 일 빈도로 해석된다.
GOTO 11.6 '리샘플링과 빈도 변환

11.3.1 날짜 범위 생성하기

pd.date_range() - 특정 빈도에 따라 지정한 길이만큼의 DatetimeIndex를 생성
기본적으로 일별 타임스탬프 생성
start=, end= 인자만 넘긴다면 periods=에 꼭 생성할 기간의 숫자를 함께 전달해야 한다.
freq= 인자에 기본 시계열 빈도를 전달한다.
Refer 표 11-4 기본 시계열 빈도
시작 시간이나 종료 시간의 타임스탬프가 존재한다면 이를 보존하고, 자정에 맞추어 타임스탬프를 정규화하고자 한다면 - normalize=True 인자를 넘긴다.

11.3.2 빈도와 날짜 오프셋

짧은 문자열로 참조되는 기본 빈도 (날짜 오프셋)와 배수의 조합으로 이루어진다.
Hour, Minute와 같은 클래스를 사용하여 시간, 분 별 빈도를 표현할 수 있다.

from pandas.tseries.offsets import Hour, Minute

기본 빈도로 쓸 시계열 빈도는 freq= 인자에 문자열로 넘기면 된다.

월별 주차

freq=WOM-3FRI - 암호같지만, 매월 3째주 금요일을 빈도로 넘겨서 지정한 기간 동안 해당 날짜를 구할 수 있다.

11.3.3 데이터 시프트

시프트는 데이터를 시간 축에서 앞이나 뒤로 이동하는 것을 의미한다. 이를 위해 Series나 DataFrame에 색인은 변경하지 않고 데이터를 앞이나 뒤로 느슨한 시프트를 수행하는 shift 메서드가 있다.
시프트 인자에 정수를 전달하여 시프트할 정도를 전달하면 시작이나 끝에 결측값이 발생한다.
shift() 메서드에 freq= 인자를 넘겨서 타임스탬프가 확장되도록 할 수 있다.

오프셋만큼 날짜 시프트하기

datetime이나 Timestamp 객체에서도 사용할 수 있다.
MonthEnd 같은 앵커드 오프셋을 연산에 사용한다면 빈도 규칙의 다음 날짜로 알아서 넘어가게 된다.
앵커드 오프셋에 rollforward(), rollback 메서드를 사용해서 알아서 넘기는 것을 조정할 수 있다.

groupby로 그루핑하여 날짜 오프셋을 스마트하게 쓸 수 있다.
Refer 11.6 resample() 함수가 사용하기 더 편하다.

11.4 시간대 다루기

파이썬도 그렇고 pandas는 pytz 모듈에서 시간대 정보를 얻어 온다.
pytz.common_timezones, pytz.timezone - 시간대 이름과 객체 확인

11.4.1 시간대 지역화와 변환

시간대 정보 확인 - print(ts.index.tz)로 색인의 tz 필드 확인
시간대를 지정해서 날짜 범위를 생성할 수 있다. - date_range()tz= 인자 전달
지역화 시간으로 변환 - tz_localize() 메서드 사용, UTC의 경우 UTC 문자열 전달
특정 시간대로 지역화되고 나면 tz_convert() 메서드로 다른 시간대로 변환 가능하다.
모두 DatetimeIndex의 인스턴트 메서드이다.

Caution 타임스탬프를 특정 시간대로 지역화하면 일광절약시간에 의한 모호하거나 존재하지 않는 시간을 체크한다.

11.4.2 시간대를 고려해서 Timestamp 객체 다루기

개별 Timestamp 객체도 시간대를 고려한 형태로 변환이 가능하다 (tz_localize, tz_convert).
생성할 때 시간대를 직접 넘겨서 생성도 가능하다 (tz= 인자에 시간대 전달).
시간대를 고려한 Timestamp 객체는 내부적으로 UTC 타임스탬프 값을 유닉스 에포크부터 현재까지 나노초로 저장하고 있다.

11.4.3 다른 시간대의 연산

서로 다른 시간대를 갖는 두 시계열이 하나로 합쳐지면 결과는 UTC이다.

11.5 기간과 기간 연산

Period 클래스 - 정수를 더하거나 빼서 정해진 빈도에 따라 기간을 이동
일반적인 기간 범위는 period_range() 함수로 생성할 수 있다. - PeriodIndex 객체가 생성
순차적인 기간을 저장하며 축 색인과 마찬가지로 사용된다.
문자열 배열의 리스트를 이용해서 PeriodIndex 클래스를 생성하는 것도 가능하다.

11.5.1 Period의 빈도 변환

PeriodIndex 객체는 asfreq() 메서드를 통해 다른 빈도로 변환할 수 있다.
연간 빈도를 월간 빈도로 변환할 수 있다.
how= 인자에 start, end 옵션을 전달하여 월로 변환

Note 써 본 기능이 아니라 언뜻 이해가 안 간다.
Example 그나마 이해가 가는 코드

rng = pd.period_range('2006', '2009', freq='A-DEC')

ts = pd.Series(np.random.randn(len(rng)), index=rng)

ts.asfreq('M', how='start')
ts.asfreq('B', how='end')

11.5.2 분기 빈도

회계연도의 끝이 어딘가에 따라 분기 빈도가 달라 지는데 Q-JAN~Q-DEC까지 12가지 경우가 모두 가능하다.
period_range()를 사용해서 분기 범위를 생성할 수 있다.

11.5.3 타임스탬프와 기간 서로 변환하기

타임스탬프로 색인된 Series와 DataFrame 객체는 to_period() 메서드를 사용해서 기간으로 변환 가능하다.
기간을 타임스탬프로 변환하려면 to_timestamp() 메서드를 사용

11.5.4 배열로 PeriodIndex 생성하기

고정된 빈도를 갖는 데이터는 종종 여러 컬럼에 걸쳐 기간에 대한 정보를 함께 저장
PeriodIndex() 메서드에 여러 컬럼의 기간에 대한 정보를 넘겨 이를 조합, DataFrame에서 사용할 수 있는 색인을 만들 수 있다.

11.6 리샘플링과 빈도 변환

리샘플링은 시계열의 빈도를 변환하는 과정을 의미
상위 빈도에서 하위 빈도로 집계 - 다운 샘플링
하위 빈도에서 상위 빈도로 - 업 샘플링
resample() 메서드 - groupby()와 비슷한 기능으로 데이터를 그룹 짓고 요약함수를 적용

Refer resample 메서드 인자

11.6.1 다운 샘플링

규칙적인 하위 빈도로 집계, 잘라낸 시계열 조각의 크기를 원하는 빈도로 정의
각 간격의 양끝 중에 어느 쪽을 닫아둘 것인가 (기본값: closed='right')
집계하려는 구간의 라벨을 간격의 시작으로 할지 끝으로 할지 여부 (기본값: label='right')
더 명확히 라벨을 보이고자 1초를 빼서 보고 싶다면 loffset='-1s'을 전달

OHLC 리샘플링

금융 분야에서 open, high, low, close를 한 번에 보이려면 resample 메서드에 how='ohlc'를 전달

11.6.2 업샘플링과 보간

그룹 당 하나의 값이 들어가고 그 사이에 결측치가 들어간다.
이 결측치에 값을 채우고자 하면 ffill() 메서드를 사용할 수 있고, limit= 인자를 넘겨서 적용할 범위를 지정할 수 있다.

11.6.3 기간 리샘플링

기간 (period)으로 색인된 데이터를 리샘플링하는 것은 타임스탬프와 유사
새로운 빈도에서 구간의 끝을 시작/끝 어느 쪽에 두어야 할지 미리 결정해야 한다. - convention=인자

11.7 이동창 함수

누락된 데이터로 인해 매끄럽지 않은 시계열 데이터를 매끄럽게 다듬을 수 있다.
rolling() 연산 - Series나 DataFrame에 대해 원하는 기간을 나타내는 window 값과 함께 호출
groupby와 비슷해 보이지만 그룹을 생성하는 대신 움직이는 창을 통해 그룹핑할 수 있는 객체를 생성

확장창 평균 - rolling 대신 expanding()메서드 사용 - 시계열의 시작 지점에서부터 창의 크기가 시계열의 전체 크기가 될 때까지 점점 창의 크기를 늘린다.

DataFrame에 적용하면 각 컬럼 별로 적용된다.

고정 크기의 기간 지정 문자열을 넘겨서 호출 - 빈도가 불규칙한 시계열일 경우 유용

11.7.1 지수 가중 함수

지수 가중 통계는 최근 값에 좀 더 많은 가중치를 두는 방법 - ewm() 연산을 사용
이동 평균을 span= 인자에 정수로 전달
단순 이동창 함수와 비교 가능하다.

11.7.2 이진 이동창 함수

두 개의 시계열을 필요로 한다.
이럴 때 TimeSeries와 DataFrame 그리고 pd.rolling.corr()을 전달하여 TimeSeries와 DataFrame의 각 컬럼 사이의 상관 관계를 구할 수 있다.

11.7.3 사용자 정의 이동창 함수

rolling이나 다른 관련 메서드에 apply()를 호출해서 이동창에 대한 사용자 정의 연산을 수행

11.8 마치며

오늘의 흔적: