[Python pandas] Database처럼 DataFrame Join/Merge 하기 : pd.merge()
Python 분석과 프로그래밍/Python 데이터 전처리 2016. 12. 3. 23:31데이터 분석을 하다 보면 여기 저기 흩어져 있는 데이터를 특정한 Key를 기준으로 병합해서 분석해야 하는 경우가 매우 많습니다.
지난번 포스팅에서는 DataFrame을 pandas의 concat() 함수를 이용해서 합치는 방법, append() 함수를 사용해서 합치는 방법을 소개하였습니다.
이번 포스팅에서는 SQL을 사용해서 Database의 Table 들을 Join/Merge 하는 것과 유사하게 Python pandas의 pd.merge() 함수를 사용해서 DataFrame을 Key 기준으로 inner, outer, left, outer join 하여 합치는 방법을 소개하도록 하겠습니다.
SQL을 사용하는데 익숙한 분석가라면 매우 쉽고 빠르게 이해하실 수 있을 것입니다. 그리고 Python의 merge() 기능은 메모리 상에서 매우 빠르게 작동함으로 사용하는데 있어 불편함이 덜할 것 같습니다.
pandas merge 함수 설정값들은 아래와 같이 여러개가 있는데요, 이중에서 'how'와 'on'은 꼭 기억해두셔야 합니다.
pd.merge(left, right, # merge할 DataFrame 객체 이름
|
먼저, pandas, DataFrame library를 importing 한 후에, 2개의 DataFrame을 만들어보겠습니다.
In [1]: import pandas as pd In [2]: from pandas import DataFrame In [3]: df_left = DataFrame({'KEY': ['K0', 'K1', 'K2', 'K3'], ...: 'A': ['A0', 'A1', 'A2', 'A3'], ...: 'B': ['B0', 'B1', 'B2', 'B3']}) ...: In [4]: df_right = DataFrame({'KEY': ['K2', 'K3', 'K4', 'K5'], ...: 'C': ['C2', 'C3', 'C4', 'C5'], ...: 'D': ['D2', 'D3', 'D4', 'D5']}) ...: In [5]: df_left Out[5]: A B KEY In [6]: df_right Out[6]: C D KEY
|
'how' 의 left, right, inner, outer 별로 위에서 만든 'df_left'와 'df_right' 두 개의 DataFrame을 'KEY' 변수를 기준으로 merge 해보겠습니다. SQL join에 익숙하신 분이라면 쉽게 이해할 수 있을 것입니다.
(1) Merge method : left (SQL join name : LEFT OUTER JOIN) |
In [7]: df_merge_how_left = pd.merge(df_left, df_right, ...: how='left', ...: on='KEY') ...: In [8]: df_merge_how_left Out[8]: A B KEY C D
|
(2) Merge method : right (SQL join name : RIGHT OUTER JOIN) |
In [9]: df_merge_how_right = pd.merge(df_left, df_right, ...: how='right', ...: on='KEY') In [10]: df_merge_how_right Out[10]: A B KEY C D
|
(3) Merge method : inner (SQL join name : INNER JOIN) |
In [11]: df_merge_how_inner = pd.merge(df_left, df_right, ...: how='inner', # default ...: on='KEY') ...: In [12]: df_merge_how_inner Out[12]: A B KEY C D
|
(4) Merge method : outer (SQL join name : FULL OUTER JOIN) |
In [13]: df_merge_how_outer = pd.merge(df_left, df_right, ...: how='outer', ...: on='KEY') ...: In [14]: df_merge_how_outer Out[14]: A B KEY C D
|
[참고] Hive 조인 문 : INNER JOIN, LEFT OUTER JOIN, RIGHT OUTER JOIN, FULL JOIN, CARTESIAN PRODUCT JOIN, MAP-SIDE JOIN, UNION ALL : http://rfriend.tistory.com/216
(5) indicator = True : 병합된 이후의 DataFrame에 left_only, right_only, both 등의 출처를 알 수 있는 부가정보 변수 추가 |
In [15]: pd.merge(df_left, df_right, how='outer', on='KEY', ...: indicator=True) Out[15]: A B KEY C D _merge
|
위에서는 indicator=True로 했더니 '_merge'라는 새로운 변수가 생겼습니다.
이 방법 외에도, 아래처럼 indicator='변수 이름(예: indicator_info)'을 설정해주면, 새로운 변수 이름에 indicator 정보가 반환됩니다.
In [16]: pd.merge(df_left, df_right, how='outer', on='KEY', ...: indicator='indicator_info') Out[16]: A B KEY C D indicator_info
|
(6) 변수 이름이 중복될 경우 접미사 붙이기 : suffixes = ('_x', '_y') |
'B'와 'C' 의 변수 이름이 동일하게 있는 두 개의 DataFrame을 만든 후에, KEY를 기준으로 합치기(merge)를 해보겠습니다. 변수 이름이 중복되므로 Data Source를 구분할 수 있도록 suffixes = ('string', 'string') 을 사용해서 중복되는 변수의 뒷 부분에 접미사를 추가해보겠습니다. default는 suffixes = ('_x', '_y') 입니다.
# making DataFrames with overlapping columns In [17]: df_left_2 = DataFrame({'KEY': ['K0', 'K1', 'K2', 'K3'], ...: 'A': ['A0', 'A1', 'A2', 'A3'], ...: 'B': ['B0', 'B1', 'B2', 'B3'], ...: 'C': ['C0', 'C1', 'C2', 'C3']}) In [18]: df_right_2 = DataFrame({'KEY': ['K0', 'K1', 'K2', 'K3'], ...: 'B': ['B0_2', 'B1_2', 'B2_2', 'B3_2'], ...: 'C': ['C0_2', 'C1_2', 'C2_2', 'C3_2'], ...: 'D': ['D0_2', 'D1_2', 'D2_2', 'D3_3']}) ...: In [19]: df_left_2 Out[19]: A B C KEY In [20]: df_right_2 Out[20]: B C D KEY
In [21]: pd.merge(df_left_2, df_right_2, how='inner', on='KEY', ...: suffixes=('_left', '_right')) ...: Out[21]: A B_left C_left KEY B_right C_right D
In [22]: pd.merge(df_left_2, df_right_2, how='inner', on='KEY') ...: Out[22]: A B_x C_x KEY B_y C_y D
|
left_on, right_on, left_index, right_index 에 대해서는 다음번 포스팅에서 소개하도록 하겠습니다.