본문 바로가기
판다스/판다스 팁

apply를 무분별하게 쓰면 안되는 이유

by 김판다t 2023. 8. 25.

오늘은 수강생이 올려준 코드에서 apply를 무분별하게 쓰고 있는 것을 발견했다.

그러면 안되는 이유에 대해서 알아보자

 

 

다음 예제 코드를 보자

 

import pandas as pd
data1 = {'날짜': ['2023-01-29', '2023-01-30', '2023-01-31', '2023-01-31', '2023-02-01'] * 200000}
df1 = pd.DataFrame(data1)

 

df1

df1은 100만행의 데이터이다 


 

 

df1의 날짜열을 datetime 형식으로 바꾸려면 아래와 같은 코드로 가능하다

 

pd.to_datetime(df1['날짜'])

 

 

그런데 수강생이 (목적은 아마도 메서드로 쓰고 싶었던 것 같다) 아래와 같은 코드로 apply로 to_datetime을 적용했다

 

df1['날짜'].apply(pd.to_datetime)

 

 

그렇지만 시리즈에 apply를 쓰면 각 셀마다 함수를 적용해 반복하기 때문에

 

1. 셀에 적용할 수 없는 판다스 함수의 경우 에러가 발생한다. (데이터 프레임이나 시리즈에만 적용되는 함수들)

 

2. 셀에도 적용할 수 있는 판다스 함수의 경우 엄청나게 시간이 오래 걸린다

 

결국 엄청나게 비효율적인 코드가 된다

 

 

다행히 to_datetime은 문자열에도 적용이 가능한 함수이다. 궁금하다면 아래 코드를 확인해보자

 

pd.to_datetime('2022-01-03')

 

그렇기에 에러는 나지 않지만 엄청나게 시간이 오래 걸린다.

 

 

 

 

얼마나 오래걸리는지 확인해보자

 

 

1. 그냥 to_datetime을 사용한 경우의 시간측정

 

import time

start = time.time()
pd.to_datetime(df1['날짜'])
end = time.time()

print(f"{end - start:.5f} sec")

 

 

0.15027 sec

 

 

 

2. apply로 to_datetime을 사용한 경우의 시간측정

 

import time

start = time.time()
df1['날짜'].apply(pd.to_datetime)
end = time.time()

print(f"{end - start:.5f} sec")

 

 

97.02660 sec

 

 

 

무려 600배가 넘는 차이가 난다.

 

차이도 많이 나지만 판다스에서 고작 100만행에 97초가 걸리는 코드는 trash code라고 볼 수 있다.

 

 

 

 

그리고 메서드로 쓰는 장점도 chain method(여러개의 메서드를 연속적으로 적용하는 것) 일 때 장점이 생기는 것이지 한번만 함수를 적용할 것이라면 굳이 method일 필요가 없다.

 

 

 

그렇지만 메서드가 필요할 때도 있을 것이다.

 

그럴 때는 chain method를 지원하는 함수 pipe를 이용하자

 

df1['날짜'].pipe(pd.to_datetime)

 

 

3. pipe로 to_datetime을 사용한 경우의 시간측정

 

 

import time

start = time.time()
df1['날짜'].pipe(pd.to_datetime)
end = time.time()

print(f"{end - start:.5f} sec")

 

 

0.16097 sec

 

 

 

pipe로 메서드를 만들면 시간도 동일하고 메서드도 사용할 수 있다

 

 

 

 

 

유튜브에서 판다스 강의 중입니다

 

https://www.youtube.com/@KimPandas