지금까지 ADP 실기시험을 다회 응시하였는데(ㅠ), 날짜와 시간 데이터에 대한 이해가 점점 중요해지고 있는 것 같다.
날짜, 시간 데이터 전처리가 미숙하면 시험장에서 굉장히 많은 시간을 허비하게 된다..
그래서, 날짜와 시간을 다룰 수 있는 파이썬 'datetime' 사용법에 대해서 정리해보고자 한다.
※ JupyterNotebook 환경에서 실습하였습니다.
1. 데이터 로드 : ' nycflights13 ' 사용
연도, 월, 일, 시간이 모두 포함된 예제 데이터 셋을 하나 골랐다.
2013년 뉴욕에서 출발한 모든 항공편에 대한 정보를 포함하고 있는 'nycflights13' 데이터셋을 사용하려고 한다.
'nycflights13' 패키지는 아래와 같이 설치 후 로드한다.
#설치
pip install nycflights13
#불러오기
import pandas as pd #csv 형식을 불러와야하므로, pandas를 불러와야 nycflights13을 로드할 수 있다.
import nycflights13
# flights 데이터셋 로드
df = nycflights13.flights
# 데이터 확인
print(df.head())
데이터를 로드하여 확인하면 아래와 같이 생겼습니다.
2. 날짜와 시간 형식으로 변환
데이터를 사용하다보면, 년, 월, 일, 시간이 각 칼럼으로 분리되어있어서 하나의 칼럼으로 합치고 싶은 경우도 있고,
하나의 칼럼에 '년월일시간'이 합쳐져있어서 개별 칼럼으로 분리해야하는 경우도 있다.
각각의 경우를 연습하고, 날짜와 시간 데이터로 처리 가능한 'dt(datetime)' 형식으로 변환한다.
1) 년월일시간 칼럼 만들기
(전처리)
'nycflights13' 데이터는 'year', 'month', 'day', 그리고 ' %_time' 형식의 칼럼들로 이루어져 있는데,
정보들을 합쳐서 년-월-일-시간 형식의 칼럼을 새로 만들어본다.
'nycflights13' 데이터 칼럼에서, ' %_time' 형식의 칼럼들은 HHMM(시간-분), 5시 17분이 '517'로 표기되어있는 형식이다.
이 중 'sched_dep_time' 칼럼을 사용, 해당 칼럼의 시간 정보를 "HH:MM"으로 변경하고
'year', 'month', 'day' 칼럼들과 합친 후 'datetime' 형식으로 변환한다.
# 'sched_dep_time' 칼럼의 데이터를 'HH:MM' 형식으로 변경
df['sched_dep_time'] = df['sched_dep_time'].apply(lambda x: '{:04d}'.format(int(x)) if pd.notnull(x) else '0000')
df['sched_dep_time'] = pd.to_datetime(df['sched_dep_time'], format='%H%M').dt.time
# 'year', 'month', 'day', 'sched_dep_time'을 합쳐 datetime 형식으로 변환
df['sched_dep_datetime'] = pd.to_datetime(df[['year', 'month', 'day']].astype(str).agg('-'.join, axis=1) + ' ' + df['sched_dep_time'].astype(str))
# 변환된 데이터 확인
print(df[['year', 'month', 'day', 'sched_dep_time', 'sched_dep_datetime']].head())
위 코드까지 실행하면 다음과 같이 출력된다.
year month day sched_dep_time sched_dep_datetime
0 2013 1 1 05:15:00 2013-01-01 05:15:00
1 2013 1 1 05:29:00 2013-01-01 05:29:00
2 2013 1 1 05:40:00 2013-01-01 05:40:00
3 2013 1 1 05:45:00 2013-01-01 05:45:00
4 2013 1 1 06:00:00 2013-01-01 06:00:00
2) '년-월-일-시간' 정보를 모두 담은 칼럼을 개별 칼럼으로 분리하기
위에서 만들었던 'sched_dep_datetime' 칼럼은 다시
dt.year/month/day/hour/minute을 사용하여 각각의 정보만을 담은 칼럼들로 분리할 수 있다.
# 연도, 월, 일, 시간, 분을 분리하여 새로운 열 생성
df['dep_year'] = df['sched_dep_datetime'].dt.year
df['dep_month'] = df['sched_dep_datetime'].dt.month
df['dep_day'] = df['sched_dep_datetime'].dt.day
df['dep_hour'] = df['sched_dep_datetime'].dt.hour
df['dep_minute'] = df['sched_dep_datetime'].dt.minute
# 변환된 데이터 확인
print(df[['sched_dep_datetime', 'dep_year', 'dep_month', 'dep_day', 'dep_hour', 'dep_minute']].head())
아래와 같이 출력된다.
sched_dep_datetime dep_year dep_month dep_day dep_hour dep_minute
0 2013-01-01 05:15:00 2013 1 1 5 15
1 2013-01-01 05:29:00 2013 1 1 5 29
2 2013-01-01 05:40:00 2013 1 1 5 40
3 2013-01-01 05:45:00 2013 1 1 5 45
4 2013-01-01 06:00:00 2013 1 1 6 0
3. 요일 추출
dt.dayofweek로 요일을 추출할 수 있다. 0은 월요일, 6은 일요일이다.
# 요일 추출 (0: 월요일, 6: 일요일)
df['weekday'] = df['sched_dep_datetime'].dt.dayofweek
# 요일 결과 확인
print(df[['sched_dep_datetime', 'weekday']].head())
4. 주말 여부 알아보기
주말은 토요일:5, 일요일:6 이므로, 아래와 같이 주말여부 칼럼을 추가해볼 수도 있다.
# 주말 여부 추가 (주말: 토요일(5), 일요일(6))
df['is_weekend'] = df['weekday'].apply(lambda x: 1 if x >= 5 else 0)
# 결과 확인
print(df[['sched_dep_datetime', 'weekday', 'is_weekend']].head())
2013년 1월 1일은 화요일(weekday 값이 1)이므로, 주말이 아니다(is_weekend 값이 0).
sched_dep_datetime weekday is_weekend
0 2013-01-01 05:15:00 1 0
1 2013-01-01 05:29:00 1 0
2 2013-01-01 05:40:00 1 0
3 2013-01-01 05:45:00 1 0
4 2013-01-01 06:00:00 1 0
5. 특정 기간 필터링
dt.to_period('*')를 사용하여, 특정 기간만 필터링이 가능하다.
* Y(연단위), Q(분기 단위), M(월 단위), W(주 단위), D(일 단위), H(시간 단위), T(분 단위), S(초 단위)
dt.to_period('M')를 사용하면 아래와 같은 방법으로 특정달(예제:1월)만 필터링 해볼 수 있다.
# 2013년 1월 데이터 필터링
df_2013_jan = df[df['sched_dep_datetime'].dt.to_period('M') == '2013-01']
# 필터링 결과 확인
print(df_2013_jan.head())
dt.to_period('Q')를 사용하면 분기 정보를 식별할 수 있으며, 특정 분기만 필터링도 가능하다.
# 'sched_dep_datetime'을 '연-분기' 형식의 기간으로 변환
df['sched_dep_quarter'] = df['sched_dep_datetime'].dt.to_period('Q')
print(df[['year', 'month', 'day', 'sched_dep_time', 'sched_dep_datetime', 'sched_dep_quarter']].head())
print(df[['year', 'month', 'day', 'sched_dep_time', 'sched_dep_datetime', 'sched_dep_quarter']].tail())
아래와 같이 출력된다.
year month day sched_dep_time sched_dep_datetime sched_dep_quarter
0 2013 1 1 05:15:00 2013-01-01 05:15:00 2013Q1
1 2013 1 1 05:29:00 2013-01-01 05:29:00 2013Q1
2 2013 1 1 05:40:00 2013-01-01 05:40:00 2013Q1
3 2013 1 1 05:45:00 2013-01-01 05:45:00 2013Q1
4 2013 1 1 06:00:00 2013-01-01 06:00:00 2013Q1
year month day sched_dep_time sched_dep_datetime sched_dep_quarter
336771 2013 9 30 14:55:00 2013-09-30 14:55:00 2013Q3
336772 2013 9 30 22:00:00 2013-09-30 22:00:00 2013Q3
336773 2013 9 30 12:10:00 2013-09-30 12:10:00 2013Q3
336774 2013 9 30 11:59:00 2013-09-30 11:59:00 2013Q3
336775 2013 9 30 08:40:00 2013-09-30 08:40:00 2013Q3
# 2013년 1분기 데이터 필터링
df_2013_q1 = df[df['sched_dep_quarter'] == '2013Q1']
# 필터링 결과 확인
print(df_2013_q1.head())
6. 특정 시간대 필터링
앞단에 언급한 dt.hour에 조건을 설정하여, 오전 9시 대 이륙 시간만 필터링해보았다.
# 오전 9시대 데이터 필터링
df_9am_flights = df[(df['sched_dep_datetime'].dt.hour >= 9) & (df['sched_dep_datetime'].dt.hour < 10)]
# 필터링 결과 확인 (필요한 칼럼만)
print(df_9am_flights[['year', 'month', 'day', 'sched_dep_time', 'sched_dep_datetime']])
아래와 같이 출력된다.
year month day sched_dep_time sched_dep_datetime
159 2013 1 1 09:00:00 2013-01-01 09:00:00
160 2013 1 1 09:00:00 2013-01-01 09:00:00
162 2013 1 1 09:00:00 2013-01-01 09:00:00
163 2013 1 1 09:05:00 2013-01-01 09:05:00
164 2013 1 1 09:00:00 2013-01-01 09:00:00
... ... ... ... ... ...
336072 2013 9 30 09:51:00 2013-09-30 09:51:00
336074 2013 9 30 09:59:00 2013-09-30 09:59:00
336075 2013 9 30 09:50:00 2013-09-30 09:50:00
336090 2013 9 30 09:59:00 2013-09-30 09:59:00
336097 2013 9 30 09:55:00 2013-09-30 09:55:00
[20312 rows x 5 columns]
여기까지 날짜와 시간 데이터를 처리할 수 있는 'datetime'의 기본 기능과 사용법을 알아보았다.
그밖에 필요한 날짜, 시간 데이터 전처리 방법과 아이디어 등은 이 글에 추가 하거나, 새 글로 정리할 예정이다.
'공부 > CS, DS' 카테고리의 다른 글
[파이썬 기초] 결측치 처리 방법 간단 정리 (0) | 2024.07.17 |
---|---|
[빅분기 실기] 파이썬 도움말 기능 알아보기 (0) | 2024.06.08 |
[파이썬 문제해결] 구글 colab에서 matplotlib 한글 깨짐 해결 방법 (1) | 2024.02.05 |
[파이썬 기초] Warning 메세지 뜨지 않게 하기 (0) | 2023.07.25 |
[파이썬 기초] Jupyter Notebook 마크다운 사용 방법 (0) | 2023.07.25 |