Part2. 공공데이터 시각화 및 탐색
이번 글에서는 Python의 Pandas를 이용하여 실제로 시계열 데이터을 다루는 방법을 알아본다.
pandas는 날짜와 시간을 캡슐화하여 사용할 수 있는 Timestamp 객체를 제공한다.
Timestamp 객체는 Numpy의 datetime64 데이터 형식을 기반으로 하며 나노초의 정밀도를 가진다.
Timestamp 생성자는 매우 유연해서 다양한 형식의 데이터를 취할 수 있다.
>>> pd.Timestamp('2016/1/10')
Timestamp('2016-01-10 00:00:00')
pandas는 Timestamp 생성자와 유사하지만, 더 많은 기능을 제공하는 to_datetime 함수를 제공한다. to_datetime 함수를 이용하면 리스트와 Series, 문자열 등의 데이터를 Timestamp 객체로 변환할 수 있다.
>>> pd.to_datetime('2015-5-13')
Timestamp('2015-05-13 00:00:00')
Timestamp 생성자 및 to_datetime 함수와 유사한 형태로 Timedelta와 to_timedelta가 있다.
Timedelta 생성자와 to_timedelta 함수는 Timedelta 객체를 생셩한다.
Timedelta 객체는 Timestamp와 Timedelta의 값을 더하거나 뺄 수 있다.
>>> pd.Timedelta('12 days 5 hours 3 minutes') * 2
Timedelta('24 days 10:06:00')
Timestamp 열을 인덱스로 설정하면 보다 다양한 시계열 분석이 가능하다. 이 경우 인덱스는 DatetimeIndex 타입이 된다.
예제로 사용하는 데이터는 서울시에서 운영하는 따릉이의 5월 한달간 대여/반납 기록 데이터로 크기는 약 135MByte이다.
데이터는 서울시 열린데이터 광장에서 수집하여 불필요한 열을 삭제한 후 필자의 구글드라이브에 공유하였다.(bikeRental_in_out_201905_min.csv)
Pandas를 이용하여 데이터를 로드하면 4열 2,221,799행의 데이터프레임을 확인할 수 있다.
rent_dt 열은 대여 일시, rent_loc열은 대여소 코드, return_dt열은 반납 일시, return_loc열은 반납소 코드이다.
각 행은 한 건의 대여와 반납을 의미한다.
아래 그림의 마지막 행은 누군가 2019년5월31일 09시19분29초에 567 대여소에서 따릉이를 대여하여 6월1일 12시경에 동일한 장소에 반납하였음을 의미한다.
Pandas의 to_datetime 함수를 이용하여 대여일시(rent_dt)와 반납일시(return_dt) 열을 datetime64 형식으로 변환한다.
Pandas의 set_index 메소드를 이용하여 대여일시(rent_dt) 열을 인덱스로 설정한다.
따릉이 데이터의 인덱스를 DatetimeIndex로 설정하였다. 이제 Pandas에서 제공하는 다양한 시계열 분석 기능을 활용할 준비가 되었다.
loc 인덱서를 이용하여 특정 시점(2019년 5월1일 12시)의 관측값 추출
at_time 메소드를 이용하여 모든 날짜의 특정 시점(12시) 관측값 추출
loc 인덱서를 이용하여 특정 기간(5월1일 00시부터 01시까지)의 모든 관측값 추출
between_time 메소드를 이용하여 모든 날짜 특정 시간 기간(00시부터 01시까지)의 관측값 추출
first 메소드를 이용하면 전체 기간의 처음부터 일정 기간의 관측값을 추출할 수 있다.
first 메소드를 사용하려면 정렬이 되어야 한다.
first 메소드의 매개변수는 DateOffset objects 모듈을 이용한다.
전체 기간에서 일(day), 주(week), 월(month) 등 간격을 정하여 집계(수량, 평균, 합계 등)하려면, resample 메소드와 DateOffset 객체를 이용한다.
아래는 DateOffset을 D(day)로 하여, 일(Day) 간격으로 따릉이 대여 건수를 집계한 결과이다.
아래는 Date Offset을 W(Week)로 설정하여 주(Week) 간격으로 따릉이 대여 건수 집계
데이터의 전체 기간에서 반복되는 시간 개념(시간, 요일 등) 별로 관측값을 집계(수량, 평균, 합계 등)하려면, DatetimeIndex의 속성을 이용한다.
DatetimeIndex의 weekday_name 속성을 이용하면 요일별 대여 건수를 집계할 수 있다. 아래 그림에서
2019년 5월중에는 금요일에 대여 건수가 가장 많고, 일요일에 가장 적다는 사실을 발견할 수 있다.
pandas 버전 0.23.0 이후에 weekday_name() 메소드가 deprecate 되었습니다. day_name() 메소드를 사용하시기 바랍니다(20.10.23)
DatetimeIndex의 hour 속성을 이용하면 시간대별 대여 건수를 집계할 수 있다.
아래는 X축을 요일로, Y축을 시간으로 집계하여 2차원으로 시각화 한 결과물이다. Pandas의 groupby를 이용하여 요일별 시간별 대여 건수를 집계하였으며, unstack 메소드를 이용하여 피벗 테이블로 변환한 후, seaborn의 히트맵 차트로 시각화 하였다.
수, 목, 금요일 18시에 가장 대여가 많음을 직관적으로 확인할 수 있다.
아래는 앞서 '선형적 기간 집계'에서 활용하였던 resampe 메소드를 이용하여 일별 대여건수를 시각화한 결과이다.
5월 19일과 5월27일은 대여 건수가 현저히 낮았다. 그 이유는 비가 왔기 때문이다(5월19일 22.0mm, 5월27일 7.1mm)
아래는 stastmodels 라이브러리를 이용하여 일별 따릉이 대여 건수를 시계열 분해하고 시각화한 결과이다.
소스 코드는 아래의 github 페이지에서 확인할 수 있습니다.