본문 바로가기
자료분석 및 코딩/파이썬

[파이썬] 4-1. 조위 자료 분석 (3) - datetime을 활용한 문자 숫자 날짜변환, 날짜/시간 연산, 수치모델 시간 변환

by 아다콘다 2023. 4. 13.

 이번에는 datetime을 활용해서 시간 데이터를 변환하고 처리하는 방법에 대해 다뤄보도록 하겠다. 대부분의 txt파일 또는 csv형식의 ascii 파일 데이터는 문자열로 정보가 입력되어 있기 때문에 이를 숫자, 값, 날짜형식으로 변환하는 과정이 필요하다. matlab에서는 datenum, datevec을 주로 활용했지만 파이썬에서는 보통 datetime 모듈을 활용한다. datetime 모듈은 문자열 또는 숫자열로 되어 있는 날짜/시간 정보를 다룰 때 활용하는 모듈이다. 날짜 연산이나 표기 형식 변환 등 다양한 목적으로 사용할 수 있다. 이번에는 문자/숫자를 날짜정보로 변환, 날짜정보를 문자/숫자열로 변환, 날짜 연산 등의 필수적인 기능에 대해서 논해보도록 하겠다.

 지난번 글에서는 아래그림처럼 dataframe으로 읽은 데이터의 시간과 조위를 numpy와 pandas의 to_numeric으로 각각 변수화하였고, 조위정보를 숫자열 값으로 변환하였다.

## data read ##
t_data = pd.read_csv('./data_2023_DT_DT_78_202301_KR.txt', sep='\t', header=3, encoding='cp949')

## modify columns name ##
aaa = t_data.columns
t_data.rename(columns={aaa[0]:'t_time', aaa[1]:'tide'},inplace=True)
# t_data.columns = ['t_time', 'tide', 'a1', 'a2', 'a3', 'a4', 'a5', 'a6', 'a7', 'a8', 'a9', 'a10', 'a11', 'a12', 'a13']

## text to number include error data ##
t_data.tide = pd.to_numeric(t_data.tide,errors='coerce')
tide = np.array(t_data.tide).astype(float)
t_time = t_data.t_time

pandas와 numpy로 읽은 시간, 조위 정보
pandas와 numpy로 읽은 시간, 조위 정보

 

1. strptime 문자열 -> 날짜형식 변환 : strptime('데이터', '날짜형식')

 strptime은 문자열을 날짜정보로 변환한다. strftime과 자주 헷갈리는데 str을 parse (분석/번역) 한다, time 으로, 줄여서 str p time 이라고 이해하면 헷갈리지 않는다. 활용법은 strptime(문자열, 표기형태)와 같이 사용한다. 위 데이터를 보면 날짜(시간)정보는 "연/월/일 시:분:초" 로 표기되어 있다. 따라서, strptime(t_time, '%Y/%m/%d %H:%M:%S') 와 같이 입력하면 된다. 또한 strptime은 datetime모듈 안의 datetime 함수 안의 기능이므로 datetime.datetime.strptime 과 같이 사용한다.

  • %Y : 연도 Year (대문자로 입력)
  • %m : 월 month (소문자로 입력 / 대문 M은 분-minute임)
  • %d : 일 day (소문자로 입력)
  • %H : 시 Hour (대문자로 입력 - 시간정보는 대문자 입력)
  • %M : 분 Minute (대문자로 입력 - 시간정보는 대문자 입력)
  • %S : 초 Seconds (대문자로 입력 - 시간정보는 대문자 입력)
bbb = datetime.datetime.strptime(t_time[0],'%Y/%m/%d %H:%M:%S')
print(bbb)

datetime strptime으로 변환한 날짜정보
datetime strptime으로 변환한 날짜정보

1.1 행렬로 구성된 날짜데이터 : for문으로 변

 하지만 t_time 데이터는 44640개의 행렬이다. datetime의 strptime은 단일 문자열에만 적용된다. 따라서 이런 경우에는 for문을 활용하여 변환한다.

time = [datetime.datetime.strptime(t_time[i],'%Y/%m/%d %H:%M:%S') for i in range(len(t_time))]

 time이라는 변수는 행렬을 의미하는 [ ]로 묶어서 입력하고, for문의 반복변수 i로 t_time의 행을 지정하여 변환한다. 명령 마지막에 for문을 입력하면 된다(range로 범위를 지정하며 범위는 t_time의 길이만큼 입력하면 된다.). 그럼 아래와 같이 시간정보로 저장된 'time'이란 변수를 확인할 수 있다.

for문을 활용한 행렬의 시간형식으로 변환
for문을 활용한 행렬의 시간형식으로 변환

 

2. strftime 날짜정보 -> 문자열 변환 : strftime('날짜정보', '표기형식')

 strftime은 날짜정보를 문자열로 변환한다. 이 역시 헷갈리는데 str(string, 문자) format(형식) time(시간) "문자열 형식의 시간" 으로 이해하면 된다. 사용법도 strptime과 비슷하다. 날짜정보와 표기할 형식을 지정하면 된다. 기존 날짜정보가 2023-01-01 00:00:00 과 같이 "연/월/일 시:분:초" 형식이므로 위 strptime과 같이 '%Y/%m/%d %H:%M:%S' 로 형식을 지정하면 아래와 같이 기존 데이터와 동일한 문자데이터가 출력된다.

datetime strftime으로 시간정보의 문자열 변환
datetime strftime으로 시간정보의 문자열 변환

 

연, 월, 일, 시, 분, 초의 표기형식은 위에서 언급했는데, 가끔 월정보를 Jan, 또는 January로 표기할 때도 있고, 요일을 Mon, Monday로 표기하기도 한다. 또한 숫자로 표기해도 1, 또는 01과 같이 표기형식이 다를 수 있는데 자주 쓰이는 표기형식을 아래 표에 나타내었다.

분류 옵션형식 의미 예시
연도 %y 두자리 숫자 연도 (0포함) 00, 01, ..., 99
%-y 숫자 연도 (0미포함) 0, 1, ..., 99
%Y 네자리 숫자 연도 2000, 2001, ..., 2023
%b 영문 월 약자 Jan, Feb, ..., Dec
%B 영문 월 January, February, ...
%m 두자리 숫자 월 (0포함) 01, 02, ..., 12
%-m 숫자 월 (0미포함) 1, 2, ..., 12
요일 %a 영문 요일 약자 Mon, Tue, ...
%A 영문 요일 Monday, Tuesday, ...
%w 요일번호 (0~6, 0이 일요일) 0, 1, 2, ..., 6
%d 두자리 숫자 일 (0포함) 01, 02, ..., 30
%-d 숫자 일 (0미포함) 1, 2, ..., 30
%H 두자리 숫자 (0포함) 00, 01, ..., 23
%-H 숫자 (0미포함) 0, 1, ..., 23
%I 0~12 두자리 숫자 (0포함) 01, 02, ..., 12
%-I 0~12 숫자 (0미포함) 1, 2, ..., 12
%p AM / PM 표기 AM, PM
%M 두자리 숫자 (0포함) 00, 01, ..., 59
%-M 숫자 (0미포함) 0, 1, ..., 59
%S 두자리 숫자 (0포함) 00, 01, ..., 59
%-S 숫자 (0미포함) 0, 1, ..., 59
대표시간표기형식 %c 날짜/시간 Mon Feb 12 07:06:05 2013
%x 날짜 04/12/23
%X 시간 5:37:05

 

 많은 형식이 있지만, 자료분석 목적에서는 Y, m, d, H, M, S 정도와 한자리 숫자 표기정도(-)만 기억하고 있어도 된다.

 

3. 시간연산 및 날짜연산 timedelta : datetime.timedelta(항목=숫자)

 자료분석을 하다보면 특정일로부터 며칠 전, 며칠 후, 몇시간 전, 후 등의 시간정보를 사용할 때가 많다. 시계열 타임시리즈를 그릴 때 범위를 지정한다거나, 등 간격의 특정 기간 정보를 만들거나 할 때, 주로 사용한다. 위에서 읽은 데이터의 첫번째 시간은 2023년 1월 1일 0시 0분 0초이다. 여기서 1일 후의 시간은 datetime.timedelta(days=1)을 더해주면 된다. 마찬가지로 하루 전은 datetime.timedelta(days=-1), 2주 후는 datetime.timedelta(weeks=2)와 같이 나타낸다. 주(weeks), 일(days), 시간(hours), 분(minutes), 초(seconds) 로 계산 가능하다. 옵션을 넣지 않고 숫자만 입력하면 자동으로 '일(days)'로 계산을 한다.

datetime timedelta를 활용한 시간연산
datetime timedelta를 활용한 시간연산

 

 

3.1 수치예측모델 시간계산

 조위정보 분석과는 크게 관련이 없지만 datetime과 시간 연산을 다루는 김에 수치예측모델의 시간을 변환하는 방법에 대해 다뤄보도록 하겠다. 아래는 기상청 수치예측모델인 RWW3 시간정보의 속성인데, 수치모델은 보통 시간정보를 십진수로 나타낸다. RWW3는 아래 사진처럼 십진수의 초, seconds로나타내고 기준일은 1970년 1월 1일이다. 따라서 1970년 1월 1일부터 해당시점이 몇 초 이후인가를 나타낸 것이다. 만약 1970년 1월 1일 1시의 시간정보는 기준시점으로부터 1시간(3600초)이 지난 시점이므로 3600으로 나타낸다.

기상청 수치예측모델의 시간 메타정보
수치모델정보의 시간정보 예시
수치모델정보의 시간정보 예시

 실제 RWW3의 시간정보를 읽어보면, 위와 같이 1438819200 ~ 으로 되어있다. 이는 1970년 1월 1일로부터 1438819200 초가 지났다는 의미이다. 따라서, 1970년 1월 1일 + 1438819200초를 더해주면 되고, 이는 datetime.datetime(1970,1,1) + datetime.timedelta(seconds=143881920) 과 같이 계산할 수 있다. 그럼 아래와 같이 2015년 8월 6일이라는 우리가 아는 시간형식으로 변환할 수 있다.

날짜형식으로 변환된 수치예측델의 time
날짜형식으로 변환된 수치예측델의 time

 위에서 읽은 시간 정보는 wtime이란 행렬로 되어 있으므로 위에서 설명한 행렬을 문자로 변환하는 for문을 활용한다. 그럼 아래와 같이 변환된다.

날짜형식으로 변환된 수치예측델의 time 행렬
날짜형식으로 변환된 수치예측델의 time 행렬

 

그럼 이제 조위정보도 숫자로 변환하였고, 시간정보도 날짜형식으로 변환을 완료하였다. plot을 그려보면 아래과 같이 조위 시계열을 확인할 수 있다. 다음에는 조화분해, 분조성분, 대조차와 소조차 등 조위정보의 실제분석과 관련된 내용에 대해 다뤄보도록 하겠다.

전처리한 조위정보 시계열
전처리한 조위정보 시계열

 

반응형