파이썬에서 시간에 따른 조건을 실행하는 법이 궁금합니다.

조회수 1126회

이번에 파이썬을 처음 배우고 프로젝트 활동을 하게 됐습니다. 아직 모르는 게 많아 시도하는 데에 의미를 둔 활동이지만 검색을 해보아도 더이상 진행되지 않아 질문드립니다.

주어진 데이터에서 time 열의 초 단위는 제거하고 그 후 30분 미만의 숫자면 15, 30분 초과의 숫자면 45로 변형하기 위해서 밑과 같은 코드를 짜보았지만 실행되지 않습니다.

print(df['time'][1].minute<10) 부분에서 True값이 나오는 것을 보고

for문 이후 if df['time'][i].minute >=30: 를 통해 진행하려 했는데

Traceback (most recent call last):
  File "D:\파이썬\1학기 프로젝트\전처리.py", line 12, in <module>
    if df['time'][i].minute >=30:
AttributeError: 'str' object has no attribute 'minute'

이라고 뜹니다. 어느 부분에서 잘못됐는지, 어떠한 방식으로 풀어가야하는 지 알려주시면 대단히 감사하겠습니다.

import pandas as pd

import datetime as dt
#데이터 불러오기
df = pd.read_csv("D:\\파이썬\\1학기 프로젝트\\연습용.csv")

# 분단위 변경
df['time'] = pd.to_datetime(df['time'])
print(df['time'][1].minute<10) #Out: True

for i in range(42):
    if df['time'][i].minute >=30:
        df['time'] = df['time'].dt.strftime('%H:45')
    else:
        df['time'] = df['time'].dt.strftime('%H:15')

print(df)

연습용.csv

store_id,date,time,card_id,amount,installments,days_of_week,holyday
0,2016-12-14,18:05:31,d297bba73f,5,,2,0
0,2016-12-14,18:05:54,d297bba73f,-5,,2,0
0,2016-12-19,12:42:31,0880849c05,144,,0,0
0,2016-12-19,12:48:08,8b4f9e0e95,66,,0,0
0,2016-12-19,13:31:08,7ad237eed0,24,,0,0
0,2016-12-19,13:36:39,30b1422f77,44,,0,0
0,2016-12-19,14:00:23,6dd8dad5ab,146,,0,0
0,2016-12-19,14:01:36,a4a425c5d2,6,,0,0
0,2016-12-19,14:09:46,f213c011fe,306,,0,0
0,2016-12-19,14:13:02,a185b7b11f,51,,0,0
0,2016-12-19,14:51:28,5af79433af,26,,0,0
0,2016-12-19,15:25:32,0beb503a74,20,,0,0
0,2016-12-19,16:15:56,3f90c1e570,72,,0,0
0,2016-12-19,16:19:16,1a04d9a6eb,25,,0,0
0,2016-12-19,16:54:46,2e14c077ba,111,,0,0
0,2016-12-19,16:55:18,cd96a7b3f6,33,,0,0
0,2016-12-19,17:08:05,202b265f07,14,,0,0
0,2016-12-19,17:30:31,a6ac2a951f,50,,0,0
0,2016-12-19,17:36:09,5d7132c0ba,75,,0,0
0,2016-12-19,18:06:15,1606e4dd61,18,,0,0
0,2016-12-19,18:07:19,2c82181047,124,,0,0
0,2016-12-19,18:31:14,342f914c88,81,,0,0
0,2016-12-19,18:37:29,9efac78d9b,14,,0,0
0,2016-12-19,18:38:15,29a3af593e,18,,0,0
0,2016-12-19,18:49:08,7cdef6ec56,121,,0,0
0,2016-12-19,18:49:26,931b32930e,11,,0,0
0,2016-12-19,18:50:51,9713246b70,45,,0,0
0,2016-12-19,18:54:35,c60ecb9b3a,79,,0,0
0,2016-12-19,18:55:58,ba32ffa324,74,,0,0
0,2016-12-19,19:05:09,9bfde99e08,50,,0,0
0,2016-12-19,19:08:36,1b6c8b98b8,49,,0,0
0,2016-12-19,19:15:17,1a04d9a6eb,42,,0,0
0,2016-12-19,19:16:47,f4821f6036,64,,0,0
0,2016-12-19,19:35:42,64ac69ab19,65,,0,0
0,2016-12-19,19:36:03,246fe0d9f5,55,,0,0
0,2016-12-19,19:36:58,bf7f4c1f67,86,,0,0
0,2016-12-19,19:39:42,d7d9342abd,106,,0,0
0,2016-12-19,20:00:22,4b2592e323,121,,0,0
0,2016-12-19,21:12:24,50ae174fca,90,,0,0
0,2016-12-19,21:32:08,7eb2ed3e09,18,,0,0
  • int 형으로도 바꿔보려해도 오류가 뜨고 타임스탬프에 관한 것도 찾아봤지만 잘 이해가 되지 않았습니다. 김태윤 2021.5.11 00:05

2 답변

  • 좋아요

    2

    싫어요
    채택 취소하기
    from io import StringIO
    import pandas as pd
    
    txt = """store_id,date,time,card_id,amount,installments,days_of_week,holyday
    0,2016-12-14,18:05:31,d297bba73f,5,,2,0
    0,2016-12-14,18:05:54,d297bba73f,-5,,2,0
    0,2016-12-19,12:42:31,0880849c05,144,,0,0
    0,2016-12-19,12:48:08,8b4f9e0e95,66,,0,0
    0,2016-12-19,13:31:08,7ad237eed0,24,,0,0"""
    
    
    def main():
    
        df = pd.read_csv(StringIO(txt))
        print(df)
    
    
        def conv_time(s: str):
            s_ = s[-5:]
            if s_ < "30:00":
                return s[:3] + "15:00"
            return s[:3] + "45:00"
    
    
        df["time_"] = df["time"].apply(conv_time)
    
        print(df)
    
        df["datetime"] = df["date"] + " " + df["time_"]
        df["datetime"] = pd.to_datetime(df["datetime"])
    
    
        print(df.info())
        print(df.to_markdown())
    
    if __name__ == "__main__":
        main()    
    

    예제를 짜 봤습니다. 마지막 결과는 다음과 같아요.

    x store_id date time card_id amount installments days_of_week holyday time_ datetime
    0 0 2016-12-14 18:05:31 d297bba73f 5 nan 2 0 18:15:00 2016-12-14 18:15:00
    1 0 2016-12-14 18:05:54 d297bba73f -5 nan 2 0 18:15:00 2016-12-14 18:15:00
    2 0 2016-12-19 12:42:31 0880849c05 144 nan 0 0 12:45:00 2016-12-19 12:45:00
    3 0 2016-12-19 12:48:08 8b4f9e0e95 66 nan 0 0 12:45:00 2016-12-19 12:45:00
    4 0 2016-12-19 13:31:08 7ad237eed0 24 nan 0 0 13:45:00 2016-12-19 13:45:00

    예제에서 핵심은 conv_time 함수입니다. time 컬럼이 문자열이고, 문자열의 마지막 5문자만 가지고 "30:00"과 대소비교를 합니다. 문자열의 대소비교는 사전배열 순서이고, 숫자도 자릿수와 포맷이 동일하다면 일반적인 수치형처럼 비교가 가능합니다.

    그렇게 컬럼을 하나 더 만들고, date 컬럼과 더하고, datetime 으로 변환하여 datetime 형의 컬럼을 최종적으로 만들어 냈습니다.

    • 그렇군요! 굳이 다른 형식으로 바꿀 필요없이 문자열인 상태로 비교를 할 수도 있다는 걸 알았습니다. 어떤식으로 작동하는 지 이해했습니다. 그런데 conv_time(s: str)에서 s: str은 무엇인지 알려주실 수 있으신가요? 김태윤 2021.5.11 20:35
    • 타입힌트입니다. s 가 문자열타입이라고 알려주어서 정적분석 등에 도움을 줍니다. nowp 2021.5.12 07:10
    • 감사합니다! 김태윤 2021.5.13 05:15
  • csv파일 제일 첫 줄을 보면 다음과 같습니다.

    store_id,date,time,card_id,amount,installments,days_of_week,holyday
    

    str 에러는 아마 이 첫 줄 때문에 변환 에러가 발생하는 것으로 보이는데요.

    이렇게 베이스가 되는 자료의 형태가 일정하지 않다면 일정한 조건이 충족될 때만 작업을 하도록 해주어야 합니다.

    이런 경우에는 if문을 통해 작업이 가능할 때만 하도록 지정하거나, try문을 통해 에러가 발생할 경우 어떻게 할지 설정하는 것으로 해결할 수 있을 것으로 보입니다.

    import pandas as pd
    
    import datetime as dt
    #데이터 불러오기
    df = pd.read_csv("D:\\파이썬\\1학기 프로젝트\\연습용.csv")
    
    # 분단위 변경
    df['time'] = pd.to_datetime(df['time'])
    print(df['time'][1].minute<10) #Out: True
    
    for i in range(42):
        if df['time'][i].minute > 0 or df['time'][i].minute <= 0:
            if df['time'][i].minute >= 30:
                df['time'] = df['time'].dt.strftime('%H:45')
            else:
                df['time'] = df['time'].dt.strftime('%H:15')
    
    print(df)
    

    또는

    for i in range(42):
        try:
            if df['time'][i].minute >= 30:
                df['time'] = df['time'].dt.strftime('%H:45')
            else:
                df['time'] = df['time'].dt.strftime('%H:15')
        except:
            pass
    
    print(df)
    
    • 아닙니다. pd.read_csv 가 첫줄 잘 처리해 줍니다. nowp 2021.5.11 10:49
    • 아.. 그렇군요 초보자 2021.5.11 12:05
    • 원하는 결과는 안나왔지만 답변 감사드립니다 김태윤 2021.5.11 20:19

답변을 하려면 로그인이 필요합니다.

프로그래머스 커뮤니티는 개발자들을 위한 Q&A 서비스입니다. 로그인해야 답변을 작성하실 수 있습니다.

(ಠ_ಠ)
(ಠ‿ಠ)