ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 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 해두자.

     

    끝.

    댓글

Designed by Tistory.