-
pandas DataFrame join merge concat 연산 속도 비교데이터분석 2021. 7. 30. 01:00
0. Intro
pandas DataFrame을 join해야하는 경우는 매우매우 빈번하다.
그래서 join 방법들을 모두 정리해볼까 한다.
# 준비한 데이터는 다음과 같음 print(raw.shape) # (9142946, 21) print(address.shape) # (1396049, 11)
1. 단일 column 기준 join
한 개의 column을 기준으로 join하는 방법들과 성능은 다음과 같음
결론: join 할 때 index를 바로 지정하지 말자;;
# pd.merge 사용 %%timeit merge_on = pd.merge(raw, address, how='left', left_on='CI', right_on='CI') # 42.1 s ± 178 ms per loop (mean ± std. dev. of 7 runs, 1 loop each) # 데이터프레임.merge 사용 %%timeit merge_on2 = raw.merge(address, how='left', left_on='CI', right_on='CI') # 42.7 s ± 894 ms per loop (mean ± std. dev. of 7 runs, 1 loop each) # join 할 때 index 바로지정 & on 파라미터 %%timeit join_on = raw.join(address.set_index('CI'), how='left', on='CI', rsuffix='_y') # 41.3 s ± 372 ms per loop (mean ± std. dev. of 7 runs, 1 loop each) # join 할 때 index 바로지정 %%timeit join_on2 = raw.set_index('CI').join(address.set_index('CI'), how='left', rsuffix='_y') #1min 2s ± 741 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
2. 단일 index 기준 join
한 개의 index를 기준으로 join하는 방법들과 성능은 다음과 같음
# 일단 index 지정은 빠름~ %%timeit address2 = address.set_index('CI') raw2 = raw.set_index('CI') # 1.48 s ± 29.6 ms per loop (mean ± std. dev. of 7 runs, 1 loop each) # pd.merge 사용 %%timeit merge_index = pd.merge(raw2, address2, how='left', left_index=True, right_index=True) # 58 s ± 323 ms per loop (mean ± std. dev. of 7 runs, 1 loop each) # join 사용 %%timeit join_index = raw2.join(address2, how='left', rsuffix='_y') # 57.7 s ± 255 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
join을 index로 할 수 있다면, pd.concat을 추가로 활용할 수 있다
하지만, unique index인 경우에만 가능하다.
# pd.concat 사용: unique index가 아니면 불가.. # %% %%timeit concat_index = pd.concat([raw2, address2], axis=1) # InvalidIndexError: Reindexing only valid with uniquely valued Index objects
3. index를 sorting 하고 join
분명 index를 쓰면 더 빠르다고 했는데 이상해서 sorting을 먼저 해봤다.
(index가 빠름 출처: https://stackoverflow.com/questions/40860457/improve-pandas-merge-performance)
# 일단 정렬: 시간이 쫌 걸린다 %%timeit address3 = address2.sort_index() raw3 = raw2.sort_index() # 22.1 s ± 178 ms per loop (mean ± std. dev. of 7 runs, 1 loop each) # sort 이후 merge %%timeit merge_index3 = raw3.merge(address3, how='left', left_index=True, right_index=True) # 38.5 s ± 185 ms per loop (mean ± std. dev. of 7 runs, 1 loop each) # sort 이후 join %%timeit join_index2 = raw3.join(address3, how='left', rsuffix='_y') # 38 s ± 102 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
4. 결론
그냥 생각나는 방식으로 쓰고,
join을 많이 반복하는 경우 미리 index 기준으로 sorting 해두자.
끝.
'데이터분석' 카테고리의 다른 글
[tensorflow 2.0] optimizer learning rate schedule (0) 2019.12.09 [tensorflow 2.0] tf.pad (0) 2019.12.02 [tensorflow 2.0] tf.data.Dataset enumerate (0) 2019.12.01 [tensorflow 2.0] tf.tile (0) 2019.11.14 [Tensorflow 2.0] custom gradient 함수로 reverse gradient 구현하기 (0) 2019.11.07