날짜,시간 데이터 전처리 (feat. Series,Dataframe)
*위의 파일을 이용하여 날짜와 시간 데이터 전처리하였습니다.
import pandas as pd
import numpy as np
#df_merged_mean = pd.read_csv('파일위치주소',encoding='UFT-8 또는 CP949')
주소가 어디인지 모르시는 분들은 아래의 글을 참고해주세요.
https://pastryofjsmath.tistory.com/23
파이썬 데이터프레임 불러오기(txt->csv->read.csv)
우리는 대게 excel(xsl),txt 데이터에서 우리는 정보를 얻습니다. txt는 데이터를 받으면 헤더부분이나 따로 떼어두는 경우도 있기 때문에.. 간혹 사용한다고 합니다. 그리고 csv파일로 바꾸는 이유는
pastryofjsmath.tistory.com
pd.to_datetime()에서 Series,Dataframe에 대한 문제점은 맨 밑에 다루었습니다.
우선 맨 1열의 Unnamed:0가 거슬리니 제거합니다.
df_merged_mean.drop('Unnamed: 0',axis=1)
이제 강의시작시간과 개강일 마지막으로 종강일을 처리하고 종강일과 개강일의 차이 총 일수를 체크해보겠습니다.
pd.to_datetime을 사용하려면 일정 표준화된 형식을 지켜줘야 합니다.
하지만 선형대수학 행의 강의시작시간이 '30분'이 붙어 있어서 표준화되어 있지 않습니다. 그렇다면 남은 곳에서도 '00분'을 시켜주면 되겠습니다. 13시 00분 같이 말이죠.
#일정한 규칙이 없으므로, 규칙을 아예 만들어버리자. ~시 ~분
df_merged_mean['강의시작시간']=df_merged_mean['강의시작시간'].str.extract(r'(\d+시)').fillna('00시')+df_merged_mean['강의시작시간'].str.extract(r'(\d+분)').fillna('00분')
df[col].str.extract(r'(data)') 는 df의 col에서 data가 포함되어있으면 모두 추출해버리는 방법이다.
df_merged_mean['강의시작시간'].str.extract(r'(시)')이면, df_merged_mean['강의시작시간']의 모든 '시'를 뽑아내는거죠.
근데 거기에 '몇'이라는 수치가 있으니까 \d(정수)를 해서 '\d시'라고 나타내는거죠.
위와 같이 나타냈으면, pd.to_datetime에서 format을 제대로 사용 할 수 있습니다.
만약 초단위는 필요 없다 싶으시면, .dt.strftime('%H:%M')이렇게 사용하시면 됩니다.
pd.to_datetime(df_merged_mean['강의시작시간'],format='%H시%M분').dt.time
pd.to_datetime(df_merged_mean['강의시작시간'],format='%H시%M분').dt.strftime('%H:%M')
df_merged_mean['강의시작시간']=pd.to_datetime(df_merged_mean['강의시작시간'],format='%H시%M분').dt.strftime('%H:%M')
df_merged_mean
다음은 개강일입니다. 개강일은 두가지 버전이 있습니다.
1.문자로 타입을 변경 후 글자 추출.
2.pd.to_datetime
우선 문자인지 확인을 해야합니다. df.dtypes를 해주어 object인지 확인해주세요. 그리고 .str[] 위치를 찾아 문자를 결합해주심 됩니다.
df_merged_mean['개강일']=df_merged_mean['개강일'].astype('str')
df_merged_mean['개강일'].str[0:2] + "-" +df_merged_mean['개강일'].str[2:4] + "-" +df_merged_mean['개강일'].str[4:]
두번째로는 pd.datetime입니다.
pd.datetime은 항상 형태를 맞춰줘야합니다. format이 xxxx년 xx월 xx일 xx시xx분xx초의 규격을 맞춰두었기 때문에, 이렇게 데이터를 만들어줘야합니다.
df_merged_mean['개강일']
df_merged_mean['개강일']='20' + df_merged_mean['개강일']
df_merged_mean['개강일']
pd.to_datetime(df_merged_mean['개강일'],format = '%Y%m%d')
다음은 종강일입니다.
*수정(240508): str로 변환하지 않고 format자체를 아래와 같이 변경하시면 바로 가능합니다.
pd.to_datetime(df2['종강일'],format='%Y년%m월%d일')
또는 번거롭지만 원래 하던대로 str[위치]를 사용하여 했습니다.
이제 형태가 갖추어졌으니 df[col].str[]+"-"df[col].str[] 이런식으로 나타내던가 pd.to_datetime으로 하시면 되겠습니다,
마지막으로 날짜 남은 계산을 하는 방법입니다. pd.to_datetime으로 하셨다면, 두 컬의 차로 바로 가능합니다.
df_merged_mean['개강일']=pd.to_datetime(df_merged_mean['개강일'],format = '%Y%m%d')
df_merged_mean
df_merged_mean['종강일'].str[0:2]+df_merged_mean['종강일'].str[3:5]+df_merged_mean['종강일'].str[6:8]
'20'+df_merged_mean['종강일'].str[0:2]+df_merged_mean['종강일'].str[4:5]+df_merged_mean['종강일'].str[6:8]
df_merged_mean
df_merged_mean['종강일'] = '20'+df_merged_mean['종강일'].str[0:2]+'0'+df_merged_mean['종강일'].str[4:5]+df_merged_mean['종강일'].str[6:8]
df_merged_mean.dtypes
pd.to_datetime(df_merged_mean['종강일'],format='%Y%m%d')
df_merged_mean['종강일']=pd.to_datetime(df_merged_mean['종강일'],format='%Y%m%d')
df_merged_mean.dtypes
df_merged_mean
df_merged_mean['종강일']-df_merged_mean['개강일']
df_merged_mean['남은일수']=df_merged_mean['종강일']-df_merged_mean['개강일']
df_merged_mean
다음엔 R로 전처리하는 내용도 올려보겠습니다.
*240515 추가하였습니다.
https://pastryofjsmath.tistory.com/35
날짜 데이터 전처리 [in R]
https://pastryofjsmath.tistory.com/28 날짜,시간 데이터 전처리*위의 파일을 이용하여 날짜와 시간 데이터 전처리하였습니다.import pandas as pdimport numpy as np#df_merged_mean = pd.read_csv('파일위치주소',encoding='UFT
pastryofjsmath.tistory.com
++240610
단일 col로 pd.to_datetime()하는 것과 기존 df['강의시작시간']으로 다시 지정해서 하는 것은 결과가 같아야하는데 단일 col로 지정하면 오류가 발생합니다. 찾아본 결과 Series,Dataframe의 차이때문이라고 합니다.
import pandas as pd
import numpy as np
#df_merged_mean = pd.read_csv('파일위치주소',encoding='UFT-8 또는 CP949')
start_time = df_merged_mean['강의시작시간'].str.extract(r'(\d+시)')+df_merged_mean['강의시작시간'].str.extract(r'(\d+분)').fillna('00분')
#start_time으로 pd.to_datetime()사용하면 오류발생.
type(start_time)
#pandas.core.frame.DataFrame
#AttributeError: 'int' object has no attribute 'lower'
#해결방법
#df.squeeze() : 단일 컬로 축소.
start_time = start_time.squeeze()
#pandas.core.series.Series
pd.to_datetime(start_time,format='%H시%M분').dt.time
0 13:00:00
1 10:30:00
2 12:00:00
3 15:00:00
4 14:00:00
5 09:00:00
Name: 0, dtype: object
#그냥 기존에 있던 컬에 넣어버리면 문제가 안됨.
df['강의시작시간'] = df['강의시작시간'].str.extract(r'(\d+시)')+df['강의시작시간'].str.extract(r'(\d+분)').fillna('00분')
pd.to_datetime(df['강의시작시간'],format='%H시%M분').dt.time
0 13:00:00
1 10:30:00
2 12:00:00
3 15:00:00
4 14:00:00
5 09:00:00
Name: 강의시작시간, dtype: object
왜 기존 컬에 넣으면 가능한지 보니 아래와 같이 나옵니다.
type(df['강의시작시간'])
#pandas.core.series.Series