안녕하세요~ 꽁냥이에요. Pandas 데이터프레임(DataFrame)에 칼럼을 for loop를 이용하여 대량으로 추가한다면 종종 아래와 같은 경고를 볼 수 있습니다.
PerformanceWarning: DataFrame is highly fragmented.
This is usually the result of calling `frame.insert` many times, which has poor performance.
Consider joining all columns at once using pd.concat(axis=1) instead
이번 포스팅에서는 해당 경고가 나오는 이유와 해결 방법에 대해서 알아보겠습니다.
PerformanceWarning: DataFrame is highly fragmented
1) 경고 발생 이유
먼저 Pandas와 Numpy를 임포트 합니다.
import pandas as pd
import numpy as np
이제 빈 데이터프레임(DataFrame)에 1000개의 칼럼을 만들어주고자 합니다. 하나의 칼럼에는 200개의 랜덤 숫자를 포함하고 있어요.
%%time
df = pd.DataFrame()
for i in range(1000):
df[str(i)] = np.random.randn(200)
코드를 실행하면 아래와 같이 경고가 뜨게 됩니다. 실행시간은 278ms 네요.
해당 경고가 뜨는 이유는 for loop에서 칼럼 삽입 연산 insert가 많이 호출되었기 때문입니다. insert는 특정 위치에 칼럼을 배치하는 연산으로 잘못하면 비효율적인 성능을 낼 수 있다고 경고 메시지가 알려주고 있어요.
2) 해결 방법
해결 방법 또한 친절하게 메시지가 알려주고 있어요. 바로 concat을 사용하는 것입니다. 위와 같은 작업을 concat으로 해보겠습니다. 방법은 간단합니다. 컴프리헨션(Comprehension)을 이용하여 하나의 칼럼을 갖는 데이터프레임을 하나의 튜플에 넣고 concat에 넣어주면 됩니다. 열 방향으로 합쳐야 하기 때문에 axis=1로 지정해 주고요.
%%time
df = pd.concat((pd.DataFrame(np.random.randn(200), columns=[str(i)]) for i in range(1000) ), axis=1)
코드를 실행하면 아까와 같은 경고 메시지는 나타나지 않습니다. 또한 시간이 두 배 정도 단축되었습니다.
하지만 끝이 아닙니다. 데이터프레임(DataFrame)이 아닌 Series를 이용하면 더 빠르게 같은 작업을 수행할 수 있습니다.
%%time
df = pd.concat((pd.Series(np.random.randn(200), name=str(i)) for i in range(1000)), axis=1)
기존 for loop를 사용할 때보다 약 4배 빨라졌어요. ㄷㄷ;;
오늘은 Pandas를 이용할 때 종종 접하는 경고를 해결하는 방법에 대해서 알아보았습니다. 오늘 내용 알아두시면 더 빠른 데이터 전처리를 하실 수 있을 거예요. 지금까지 꽁냥이었습니다. 다음에도 좋은 주제로 찾아뵙겠습니다. 안녕히 계세요.
'데이터 분석 > 데이터 전처리' 카테고리의 다른 글
[Numpy] 원-핫 인코딩(One-Hot Encoding) 간단하게 해보기 (feat. eye) (0) | 2023.04.16 |
---|---|
[Pandas Tip] 오류 해결 - SettingWithCopyWarning (1) | 2023.02.10 |
[Pandas] 40. 데이터프레임(DataFrame)의 특정 칼럼으로 데이터 순위 매기기 (feat. rank) (2) | 2023.01.21 |
[Pandas] 39. 데이터프레임 열(칼럼) 또는 행 똑같이 맞추기 (feat. align) (0) | 2023.01.19 |
[Pandas] 38. 특정 칼럼(Pandas Series)의 누적합, 누적곱, 누적 최대값, 누적 최소값 구하기(feat. cumsum, cumprod, cummax, cummin) (0) | 2023.01.18 |
댓글