Must Learning With Statistics

python 시간 데이터 다루기 본문

Python Code

python 시간 데이터 다루기

Doublek Park 2020. 2. 22. 15:41

Pandas 시간 다루기

이번 포스팅은 Pandas에서 시간을 다루는 방법에 대해 다루어보도록하겠습니다. 데이터를 분석하는데에 있어서, 시간 데이터를 다룰 때는 참 까다롭습니다. 데이터마다 입력 포맷이 다른 것은 물론이며, 일반 데이터와 동일하게 처리하는데에는 문제가 있기 떄문입니다. 기본적으로 날짜를 다루기 위해서는 datetime 모듈을 불러와야 합니다.

1. 현재시간 불러오기

import datetime

# 현재시간(시스템 시간) 불러오기
datetime.datetime.now()
datetime.datetime(2020, 2, 22, 15, 38, 42, 1214)

이 포스팅이 작성되고 있는 시간이 기록되는 것을 확인하실 수가 있습니다.

2. 시간 포맷 변환하기

시간 데이터에는 포맷이 여러가지가 있습니다, 예를 들어, "년-월-일"로 표현을 할 때도 있고, 요일만 표현을 해야될 때도 있습니다. 필요에 따라서는 년도, 월, 요일 등을 따로 추출해야 되는 경우도 존재합니다.

# 시간 포맷 변환하기

dt = datetime.datetime.now()
dt
datetime.datetime(2020, 2, 22, 15, 38, 42, 883773)
  • 년, 월, 일 추출
print(dt.year) # 년
print(dt.month) # 월
print(dt.day) #일 
2020
2
22
  • 시간, 분, 초 추출
print(dt.hour) # 시간
print(dt.minute) # 분
print(dt.second) # 초
15
38
42
  • 요일 추출

요일의 경우에는 일,월,화,수,목,금,토 이런식으로 나오는 것이 아니라 0 ~ 6사이의 숫자로 표현이 됩니다. 0은 월요일이며, 6은 일요일에 해당됩니다.

print(dt.weekday())
5

만약에 isoweekday를 쓸 경우 1이 월요일이며, 7이 일요일이 됩니다. 주의가 필요합니다.

dt.isoweekday()
6
  • 포맷에 따른 출력(시간 제외)
    • %a : 요일
    • %A : 요일(FULL)
    • %d : 일
    • %b : 월(Short)
    • %B : 월(Full)
    • %y : 년(OO)
    • %Y : 년(OOOO)
    • %D: 월/일/년

날짜는 제각기 지정된 포맷 형식이 있습니다. 예를 들어 "%a"는 날짜에서 요일을 가르키는 포맷입니다. "%d'는 날짜를 의미합니다.

print(dt.strftime("%a, %d %B, %y"))
print(dt.strftime("%A, %d %b, %Y"))
print(dt.strftime("%D"))
Sat, 22 February, 20
Saturday, 22 Feb, 2020
02/22/20
  • 포맷에 따른 출력(시간 포함)
    • %c : 날짜 + 시간
    • %x : 날짜
    • %X : 시간
print(dt.strftime("%c"))
print(dt.strftime("%x"))
print(dt.strftime("%X"))
Sat Feb 22 15:38:42 2020
02/22/20
15:38:42

3. 시간 연산

시간끼리 연산할 때는 주로 timedelta를 이용해서 진행이 됩니다. 이제부터 pandas를 활용하여 가상의 데이터를 만들어 진행을 해보도록 하겠습니다. 데이터는 제 전공분야인 항만 터미널에서 사용되는 선박의 입항 스케쥴을 가상으로 생성해보며 진행하도록 하겠습니다.

import pandas as pd
import numpy as np
import datetime

SHIP = pd.DataFrame(
    {"SHIP" : ['AAAA','BBBB','CCCC','DDDD','EEEE',
                  "FFFF","EEEE","JJJJ","HHHH","KKKK",
                  "LLLL","OOOO","PPPP","QQQQ","WWWW"]}
)

SHIP['Time'] = datetime.datetime.now()

SHIP

SHIP Time
0 AAAA 2020-02-22 15:38:49.730607
1 BBBB 2020-02-22 15:38:49.730607
2 CCCC 2020-02-22 15:38:49.730607
3 DDDD 2020-02-22 15:38:49.730607
4 EEEE 2020-02-22 15:38:49.730607
5 FFFF 2020-02-22 15:38:49.730607
6 EEEE 2020-02-22 15:38:49.730607
7 JJJJ 2020-02-22 15:38:49.730607
8 HHHH 2020-02-22 15:38:49.730607
9 KKKK 2020-02-22 15:38:49.730607
10 LLLL 2020-02-22 15:38:49.730607
11 OOOO 2020-02-22 15:38:49.730607
12 PPPP 2020-02-22 15:38:49.730607
13 QQQQ 2020-02-22 15:38:49.730607
14 WWWW 2020-02-22 15:38:49.730607

먼저 기본적으로 생성한 데이터는 선명을 주었으며 Time을 현재시간으로 주었습니다. 여기서 현재시간에 대해 선박의 입항예정 시간을 Random하게 주도록 하겠습니다. 계산식은 간단합니다. 현재시간 Time에 대해서 제가 생성한 난수를 더해주는 방식으로 선박의 입항예정 시간을 구해보도록 하겠습니다.

TI = np.random.randint(12, size = (1, SHIP.shape[0]))
SHIP['Time_Diff'] = TI[0]
SHIP

SHIP Time Time_Diff
0 AAAA 2020-02-22 15:38:49.730607 6
1 BBBB 2020-02-22 15:38:49.730607 6
2 CCCC 2020-02-22 15:38:49.730607 5
3 DDDD 2020-02-22 15:38:49.730607 3
4 EEEE 2020-02-22 15:38:49.730607 4
5 FFFF 2020-02-22 15:38:49.730607 0
6 EEEE 2020-02-22 15:38:49.730607 4
7 JJJJ 2020-02-22 15:38:49.730607 2
8 HHHH 2020-02-22 15:38:49.730607 5
9 KKKK 2020-02-22 15:38:49.730607 9
10 LLLL 2020-02-22 15:38:49.730607 8
11 OOOO 2020-02-22 15:38:49.730607 8
12 PPPP 2020-02-22 15:38:49.730607 4
13 QQQQ 2020-02-22 15:38:49.730607 1
14 WWWW 2020-02-22 15:38:49.730607 6

적당히 현재시간으로부터 12시간 이내로 선박이 몇 시간 후에 입항할지에 대한 정보 'Time_Diff'를 만들었습니다. 그럼 여기서 'Time'과 'Time_Diff'를 더해보도록 하겠습니다. 시간 단위로 더해줄 것이기 때문에 꼭 단위를 시간으로 설정을 해주어야 합니다.

SHIP['ETA'] = SHIP['Time'] + pd.to_timedelta(SHIP['Time_Diff'],unit = 'h')
SHIP

SHIP Time Time_Diff ETA
0 AAAA 2020-02-22 15:38:49.730607 6 2020-02-22 21:38:49.730607
1 BBBB 2020-02-22 15:38:49.730607 6 2020-02-22 21:38:49.730607
2 CCCC 2020-02-22 15:38:49.730607 5 2020-02-22 20:38:49.730607
3 DDDD 2020-02-22 15:38:49.730607 3 2020-02-22 18:38:49.730607
4 EEEE 2020-02-22 15:38:49.730607 4 2020-02-22 19:38:49.730607
5 FFFF 2020-02-22 15:38:49.730607 0 2020-02-22 15:38:49.730607
6 EEEE 2020-02-22 15:38:49.730607 4 2020-02-22 19:38:49.730607
7 JJJJ 2020-02-22 15:38:49.730607 2 2020-02-22 17:38:49.730607
8 HHHH 2020-02-22 15:38:49.730607 5 2020-02-22 20:38:49.730607
9 KKKK 2020-02-22 15:38:49.730607 9 2020-02-23 00:38:49.730607
10 LLLL 2020-02-22 15:38:49.730607 8 2020-02-22 23:38:49.730607
11 OOOO 2020-02-22 15:38:49.730607 8 2020-02-22 23:38:49.730607
12 PPPP 2020-02-22 15:38:49.730607 4 2020-02-22 19:38:49.730607
13 QQQQ 2020-02-22 15:38:49.730607 1 2020-02-22 16:38:49.730607
14 WWWW 2020-02-22 15:38:49.730607 6 2020-02-22 21:38:49.730607

분단위로 계산할 때는 unit = 'm'을 주면 됩니다.

SHIP['ETA'] = SHIP['ETA'] + pd.to_timedelta(SHIP['Time_Diff'],unit = 'm')
SHIP

SHIP Time Time_Diff ETA
0 AAAA 2020-02-22 15:38:49.730607 6 2020-02-22 21:44:49.730607
1 BBBB 2020-02-22 15:38:49.730607 6 2020-02-22 21:44:49.730607
2 CCCC 2020-02-22 15:38:49.730607 5 2020-02-22 20:43:49.730607
3 DDDD 2020-02-22 15:38:49.730607 3 2020-02-22 18:41:49.730607
4 EEEE 2020-02-22 15:38:49.730607 4 2020-02-22 19:42:49.730607
5 FFFF 2020-02-22 15:38:49.730607 0 2020-02-22 15:38:49.730607
6 EEEE 2020-02-22 15:38:49.730607 4 2020-02-22 19:42:49.730607
7 JJJJ 2020-02-22 15:38:49.730607 2 2020-02-22 17:40:49.730607
8 HHHH 2020-02-22 15:38:49.730607 5 2020-02-22 20:43:49.730607
9 KKKK 2020-02-22 15:38:49.730607 9 2020-02-23 00:47:49.730607
10 LLLL 2020-02-22 15:38:49.730607 8 2020-02-22 23:46:49.730607
11 OOOO 2020-02-22 15:38:49.730607 8 2020-02-22 23:46:49.730607
12 PPPP 2020-02-22 15:38:49.730607 4 2020-02-22 19:42:49.730607
13 QQQQ 2020-02-22 15:38:49.730607 1 2020-02-22 16:39:49.730607
14 WWWW 2020-02-22 15:38:49.730607 6 2020-02-22 21:44:49.730607

초단위로 계산할 때는 unit = 's'을 주면 됩니다.

SHIP['ETA'] = SHIP['ETA'] + pd.to_timedelta(SHIP['Time_Diff'],unit = 's')
SHIP

SHIP Time Time_Diff ETA
0 AAAA 2020-02-22 15:38:49.730607 6 2020-02-22 21:44:55.730607
1 BBBB 2020-02-22 15:38:49.730607 6 2020-02-22 21:44:55.730607
2 CCCC 2020-02-22 15:38:49.730607 5 2020-02-22 20:43:54.730607
3 DDDD 2020-02-22 15:38:49.730607 3 2020-02-22 18:41:52.730607
4 EEEE 2020-02-22 15:38:49.730607 4 2020-02-22 19:42:53.730607
5 FFFF 2020-02-22 15:38:49.730607 0 2020-02-22 15:38:49.730607
6 EEEE 2020-02-22 15:38:49.730607 4 2020-02-22 19:42:53.730607
7 JJJJ 2020-02-22 15:38:49.730607 2 2020-02-22 17:40:51.730607
8 HHHH 2020-02-22 15:38:49.730607 5 2020-02-22 20:43:54.730607
9 KKKK 2020-02-22 15:38:49.730607 9 2020-02-23 00:47:58.730607
10 LLLL 2020-02-22 15:38:49.730607 8 2020-02-22 23:46:57.730607
11 OOOO 2020-02-22 15:38:49.730607 8 2020-02-22 23:46:57.730607
12 PPPP 2020-02-22 15:38:49.730607 4 2020-02-22 19:42:53.730607
13 QQQQ 2020-02-22 15:38:49.730607 1 2020-02-22 16:39:50.730607
14 WWWW 2020-02-22 15:38:49.730607 6 2020-02-22 21:44:55.730607

시간끼리 연산을 해야될 때는 timedelta를 활용하면 간단하게 만들 수가 있습니다.

4. 시간 단위(분, 시간)로 정리하기

시간 데이터또한 분, 시간 등으로 깔끔하게 올림 반올림을 통해 깔끔하게 정리를 해야될 필요가 존재합니다. 이번에는 그 방법에 대해 알아보도록 하겠습니다. 시간을 10분단위로 정리해보도록 하겠습니다. apply와 lambda 기능을 통해 간단하게 정리를 해보도록 하겠습니다. 년, 월, 일 , 시간은 그대로 나오되, 분은 10분 단위로 나오도록 하는 방법입니다. 원리는 분을 10으로 나눈 몫에 대하여 다시 10을 곱해주는 형식입니다.

SHIP['ETA1'] = SHIP['ETA'].apply(lambda dt: datetime.datetime(dt.year, 
                                                             dt.month, dt.day,dt.hour,10*(dt.minute // 10)))
SHIP

SHIP Time Time_Diff ETA ETA1
0 AAAA 2020-02-22 15:38:49.730607 6 2020-02-22 21:44:55.730607 2020-02-22 21:40:00
1 BBBB 2020-02-22 15:38:49.730607 6 2020-02-22 21:44:55.730607 2020-02-22 21:40:00
2 CCCC 2020-02-22 15:38:49.730607 5 2020-02-22 20:43:54.730607 2020-02-22 20:40:00
3 DDDD 2020-02-22 15:38:49.730607 3 2020-02-22 18:41:52.730607 2020-02-22 18:40:00
4 EEEE 2020-02-22 15:38:49.730607 4 2020-02-22 19:42:53.730607 2020-02-22 19:40:00
5 FFFF 2020-02-22 15:38:49.730607 0 2020-02-22 15:38:49.730607 2020-02-22 15:30:00
6 EEEE 2020-02-22 15:38:49.730607 4 2020-02-22 19:42:53.730607 2020-02-22 19:40:00
7 JJJJ 2020-02-22 15:38:49.730607 2 2020-02-22 17:40:51.730607 2020-02-22 17:40:00
8 HHHH 2020-02-22 15:38:49.730607 5 2020-02-22 20:43:54.730607 2020-02-22 20:40:00
9 KKKK 2020-02-22 15:38:49.730607 9 2020-02-23 00:47:58.730607 2020-02-23 00:40:00
10 LLLL 2020-02-22 15:38:49.730607 8 2020-02-22 23:46:57.730607 2020-02-22 23:40:00
11 OOOO 2020-02-22 15:38:49.730607 8 2020-02-22 23:46:57.730607 2020-02-22 23:40:00
12 PPPP 2020-02-22 15:38:49.730607 4 2020-02-22 19:42:53.730607 2020-02-22 19:40:00
13 QQQQ 2020-02-22 15:38:49.730607 1 2020-02-22 16:39:50.730607 2020-02-22 16:30:00
14 WWWW 2020-02-22 15:38:49.730607 6 2020-02-22 21:44:55.730607 2020-02-22 21:40:00

20분 단위로 정리를 해주고 싶을 때는 분을 20으로 나누고 그 몫에 대해 다시 20을 곱해주면 됩니다.

SHIP['ETA2'] = SHIP['ETA'].apply(lambda dt: datetime.datetime(dt.year, 
                                                             dt.month, dt.day,dt.hour,20*(dt.minute // 20)))
SHIP

SHIP Time Time_Diff ETA ETA1 ETA2
0 AAAA 2020-02-22 15:38:49.730607 6 2020-02-22 21:44:55.730607 2020-02-22 21:40:00 2020-02-22 21:40:00
1 BBBB 2020-02-22 15:38:49.730607 6 2020-02-22 21:44:55.730607 2020-02-22 21:40:00 2020-02-22 21:40:00
2 CCCC 2020-02-22 15:38:49.730607 5 2020-02-22 20:43:54.730607 2020-02-22 20:40:00 2020-02-22 20:40:00
3 DDDD 2020-02-22 15:38:49.730607 3 2020-02-22 18:41:52.730607 2020-02-22 18:40:00 2020-02-22 18:40:00
4 EEEE 2020-02-22 15:38:49.730607 4 2020-02-22 19:42:53.730607 2020-02-22 19:40:00 2020-02-22 19:40:00
5 FFFF 2020-02-22 15:38:49.730607 0 2020-02-22 15:38:49.730607 2020-02-22 15:30:00 2020-02-22 15:20:00
6 EEEE 2020-02-22 15:38:49.730607 4 2020-02-22 19:42:53.730607 2020-02-22 19:40:00 2020-02-22 19:40:00
7 JJJJ 2020-02-22 15:38:49.730607 2 2020-02-22 17:40:51.730607 2020-02-22 17:40:00 2020-02-22 17:40:00
8 HHHH 2020-02-22 15:38:49.730607 5 2020-02-22 20:43:54.730607 2020-02-22 20:40:00 2020-02-22 20:40:00
9 KKKK 2020-02-22 15:38:49.730607 9 2020-02-23 00:47:58.730607 2020-02-23 00:40:00 2020-02-23 00:40:00
10 LLLL 2020-02-22 15:38:49.730607 8 2020-02-22 23:46:57.730607 2020-02-22 23:40:00 2020-02-22 23:40:00
11 OOOO 2020-02-22 15:38:49.730607 8 2020-02-22 23:46:57.730607 2020-02-22 23:40:00 2020-02-22 23:40:00
12 PPPP 2020-02-22 15:38:49.730607 4 2020-02-22 19:42:53.730607 2020-02-22 19:40:00 2020-02-22 19:40:00
13 QQQQ 2020-02-22 15:38:49.730607 1 2020-02-22 16:39:50.730607 2020-02-22 16:30:00 2020-02-22 16:20:00
14 WWWW 2020-02-22 15:38:49.730607 6 2020-02-22 21:44:55.730607 2020-02-22 21:40:00 2020-02-22 21:40:00

여기까지 시간을 다루는데 필요한 기본적인 내용을 다루었습니다. 날짜 연산은 항상 헷갈리는 작업이기 때문에 자주 사용해보는 것이 중요합니다.

'Python Code' 카테고리의 다른 글

R dpylr 주요 코드와 Python Pandas 코드 비교  (1) 2020.02.05
Comments