본문 바로가기

Python

TypeError: unsupported operand type(s) for -: 'str' and 'datetime.timedelta'

1. 밀어만 내는 파이썬을 붙잡고 상호 간의 이해가 중요함을 강조하면서 계속설득을 하고 있건만 잘 안된다.

   힘들어...

   여튼 날짜에 관한 datetime 모듈을 한번은 정리할 필요가 있어서 몇 가지를 찾아본 결과 

https://m.blog.naver.com/PostView.nhn?blogId=wideeyed&logNo=221603462366&proxyReferer=https:%2F%2Fwww.google.com%2F

 

[Pandas] 일자와 시간(dt) 처리법

Pandas를 이용하여 일자와 시간을 처리하는 방법에 대해서 알아보겠습니다.Pandas에서 지원하는 일자시간...

blog.naver.com

 

https://windybay.net/post/20/

 

파이썬 datetime 모듈로 날짜, 시간 다루기

파이썬으로 코딩을 하다 보면 날짜, 시간에 관련 처리를 할 일이 많다. 이때 사용하게 되는것이 datetime …

windybay.net

 

   위 두가지 사이트가 정리가 잘 된 것 같다. 

 

2. 원론적이고 초보적인 내용이야 차고 넘치니. 실제 어떤 곳에서 오류가 발생했는지를 또 기록해보자.

   첫 번째 참조 사이트 데이터프레임 자료를 가지고 오류 발생 원인을 찾아보자. 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
df = pd.DataFrame({'Birth':['2019-01-01 09:10:00',
                            '2019-01-08 09:20:30',
                            '2019-02-01 10:20:00',
                            '2019-02-02 11:40:50',
                            '2019-02-28 15:10:20',
                            '2019-04-10 19:20:50',
                            '2019-06-30 21:20:50',
                            '2019-07-20 23:30:59']})
 
df['Birth']
 
0    2019-01-01 09:10:00
1    2019-01-08 09:20:30
2    2019-02-01 10:20:00
3    2019-02-02 11:40:50
4    2019-02-28 15:10:20
5    2019-04-10 19:20:50
6    2019-06-30 21:20:50
7    2019-07-20 23:30:59
Name: Birth, dtype: object
cs

   

   데이터 프레임 속성은 당연히 object

   

1
2
3
4
5
6
7
8
9
10
11
12
13
# object 타입을 datetime64[ns] 타입으로 바꾼다 
df['Birth'= pd.to_datetime(df['Birth'], format='%Y-%m-%d %H:%M:%S', errors='raise')
df['Birth']
 
0   2019-01-01 09:10:00
1   2019-01-08 09:20:30
2   2019-02-01 10:20:00
3   2019-02-02 11:40:50
4   2019-02-28 15:10:20
5   2019-04-10 19:20:50
6   2019-06-30 21:20:50
7   2019-07-20 23:30:59
Name: Birth, dtype: datetime64[ns]
cs

   

   설명대로 datetime64 타입으로 변형하면 당연히 datetime64

 

1
2
3
df['Birth'].iloc[0]
 
 
cs

 

   첫 번째 행렬 값을 찍어보면 "Timestamp('2019-01-01 09:10:00')" 결과값이 표기

 

1
2
3
4
5
6
7
8
9
10
11
12
13
df['Birth_date'= df['Birth'].copy().dt.date
 
df['Birth_date']
 
0    2019-01-01
1    2019-01-08
2    2019-02-01
3    2019-02-02
4    2019-02-28
5    2019-04-10
6    2019-06-30
7    2019-07-20
Name: Birth_date, dtype: object
cs

 

   Birth_date라는 새로운 column을 만들기 위해 첫 번째 사이트에서 설명한 바와 같이 dt.date를 적용하면

   속성은 object로 변화

 

1
df['Birth_date'].iloc[0]
cs

 

   첫 번째 행렬 값을 찍어보면 "datetime.date(2019, 1, 1)" 결과값이 표기

 

1
2
3
4
5
6
7
8
9
10
11
12
df['Birth_date1'= df['Birth_date'].copy().map(lambda x: x.strftime('%Y-%m-%d'))
 
df['Birth_date1']
0    2019-01-01
1    2019-01-08
2    2019-02-01
3    2019-02-02
4    2019-02-28
5    2019-04-10
6    2019-06-30
7    2019-07-20
Name: Birth_date1, dtype: object
cs

 

   Birth_date1 이라는 새로운 column을 문자형으로 변환하면 역시 속성은 object 

 

1
df['Birth_date1'].iloc[0]
cs

   

   그러나 첫 번째 행렬 값을 찍어보면 '2019-01-01' 결과 값이 표기

 

   두 번째 사이트에서 설명되어 있는 datetime 하위 클래스인 timedelta를 이용하기 위해서는

   실제 시간을 나타내는 datetime 형식에 맞아야 한다. 

   

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
df['Birth_td'= df['Birth'].map(lambda x: x - datetime.timedelta(7)) 
df['Birth_date_td'= df['Birth_date'].map(lambda x: x - datetime.timedelta(7)) 
df['Birth_date1_td'= df['Birth_date1'].map(lambda x: x - datetime.timedelta(7)) 
 
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-131-bba52788bd7a> in <module>
----> 1 df['Birth_date1_td'= df['Birth_date1'].map(lambda x: x - datetime.timedelta(7))
 
~\Anaconda3\lib\site-packages\pandas\core\series.py in map(self, arg, na_action)
   3628         dtype: object
   3629         """
-> 3630         new_values = super()._map_values(arg, na_action=na_action)
   3631         return self._constructor(new_values, index=self.index).__finalize__(self)
   3632 
 
~\Anaconda3\lib\site-packages\pandas\core\base.py in _map_values(self, mapper, na_action)
   1143 
   1144         # mapper is a function
-> 1145         new_values = map_f(values, mapper)
   1146 
   1147         return new_values
 
pandas\_libs\lib.pyx in pandas._libs.lib.map_infer()
 
<ipython-input-131-bba52788bd7a> in <lambda>(x)
----> 1 df['Birth_date1_td'] = df['Birth_date1'].map(lambda x: x - datetime.timedelta(7))
 
TypeError: unsupported operand type(s) for -: 'str' and 'datetime.timedelta'
 
 
cs

   

   당연한 이야기지만 Birth_date1은 그냥 문자(str)이기 때문에 timedelta 속성을 이용할 수 없다. 

  

   

    df를 찍어보면 오류가 난 'Birth_date1_td' column은 빼고 출력이 된다. 

 

 

3. 당연한 거 아니냐?

   지금은 당연하다고 생각하는데 헷갈렸던 것은 dt.date를 적용하면 속성이 object로 변화되면서

   반환값이 YYYY-MM-DD 형식의 문자라 일반 속성의 문자와 같다고 생각한 부분이다.

   datetime 모듈 속성을 적용했기 때문에 반환값이 문자여도 날짜 계산이 가능하다.

 

 

4. relativetimedelta

  http://egloos.zum.com/mcchae/v/11203068

 

[Python] timedelta(months=1) 시각에 달 빼고 더하기 연산

파이썬에서 datetime 모듈에 timedelta라고 있습니다. 아주 간단한 사용은 특정 시각에 얼마만큼의 시간을 더하거나 빼는 역할을 수행합니다. (그 반대로 두 시각을 빼면 그 차이를 담고 있는 timedelta

egloos.zum.com

   timedelta 속성을 조금 더 이해해보자.