본문 바로가기

코딩/Python

[Python/파이썬] Pandas Dataframe 결합 : Merge

반응형

※ 이 글을 쓰는 사람은 SW 비전공자입니다.

※ 개인 공부를 위해 정리하는 글이며, 작성한 코드들은 효율성, 깔끔함(?) 등과는 거리가 멀 수 있습니다.

 

1편 : 2021.03.31 - [코딩/Python] - [Python/파이썬] Pandas 기초 정리 : Series, Dataframe 개념 정리

2편 : 2021.04.01 - [코딩/Python] - [Python/파이썬] Pandas 기초 정리 : 엑셀 파일(.xlsx) Dataframe으로 만들기

3편 : 2021.04.03 - [코딩/Python] - [Python/파이썬] Pandas 기초 정리 : Dataframe 내부 데이터 조회 방법

4편 : 2021.04.05 - [코딩/Python] - [Python/파이썬] Pandas 기초 정리 : Dataframe 행, 열 추가 방법

5편 : 2021.04.11 - [코딩/Python] - [Python/파이썬] Pandas 기초 정리 : Dataframe 행, 열 삭제하기(drop 함수)

6편 : 2021.04.13 - [코딩/Python] - [Python/파이썬] Pandas 기초 정리 : 원소바꾸기, dropna(), fillna()

7편 : 2021.04.24 - [코딩/Python] - [Python/파이썬] Pandas Dataframe 결합 : Concat

8편 : 2021.04.25 - [코딩/Python] - [Python/파이썬] Pandas Dataframe 결합 : Merge


  이번 포스팅에서는 merge 함수에 대해 정리한다. 이전 편에서 언급하였지만 concat은 겨우 단순히 2개의 데이터 프레임이나 시리즈를 합치는데 중점을 둔다. merge 함수의 경우 어떤 기준(key)을 가지고 데이터프레임을 결합할 수 있다.

 

  아래 자주 쓰이는 몇가지 예시를 작성하였다. 이전 편과 마찬가지로 동일한 df1, df2, df3를 가지고 테스트하였다.

 

<df 생성 코드>

dataframe 생성(엑셀 파일 통해 생성)
df1 = pd.read_excel("df_test.xlsx", engine="openpyxl", sheet_name="수강생정보")
df2 = pd.read_excel("df_test.xlsx", engine="openpyxl", sheet_name="중간고사점수")
df3 = pd.read_excel("df_test.xlsx", engine="openpyxl", sheet_name="기말고사점수")

 

#df1 : 수강생정보
      이름  나이        연락처
0     YB    30     +81-0000-0000
1     SW    29     +81-0000-0001
2     EJ    28     +81-0000-0002
3     HJ    27     +81-0000-0003
4  James    20     +81-0000-0004
5  Borwn    21     +81-0000-0005


#df2 : 중간고사점수(index 0, 4번째 점수는 일부로 중복으로 입력)
   이름   시험구분  국어  영어  수학
0  YB     중간고사  100   90     80
1  SW     중간고사   70   60     50
2  EJ     중간고사   40    5     20
3  HJ     중간고사   10    5      1
4  YB     중간고사  100   90     80


#df3 : 기말고사 점수
   이름  시험구분   국어   영어   수학
0  YB    기말고사  100     100    100
1  SW    기말고사   70      70     70
2  EJ    기말고사   20      20     20
3  HJ    기말고사   10      10    10

 

 

1. Merge 기본

 

-. df1과 df2 를 merge하면 서로 교집합이 되는 부분만 출력된다.

-. 2번에서 설명하겠지만 사실 파라미터 중 how='inner'가 default값이다.)

 

 

<코드>

print("기본 출력")
df_merge1 = pd.merge(df1, df2)
print(df_merge1)

 

기본 출력
   이름  시험구분   국어  영어  수학  나이       연락처
0  YB    중간고사   100   90    80   30    +81-0000-0000
1  YB    중간고사   100   90    80   30    +81-0000-0000
2  SW    중간고사    70   60    50   29    +81-0000-0001
3  EJ    중간고사    40    5    20   28    +81-0000-0002
4  HJ    중간고사    10    5    1    27    +81-0000-0003

 

 

2. how 파라미터 사용하기

 

 

1) how = 'inner'

 

-. 위 1번과 마찬가지 결과이다.

-. how='inner'는 2개 데이터프레임간 교집합을 출력한다.

-. default이기 때문에 생략하여도 무관하다.

 

 

<코드>

print("교집합")
df_merge3 = pd.merge(df1, df3, how='inner')
print(df_merge3)

 

교집합
  이름 나이    연락처      시험구분   국어   영어   수학
0  YB  30  +81-0000-0000  기말고사  100    100    100
1  SW  29  +81-0000-0001  기말고사   70     70     70
2  EJ  28  +81-0000-0002  기말고사   20     20     20
3  HJ  27  +81-0000-0003  기말고사   10     10     10

 

 

2) how ='outer'

 

-. outer로 설정시 합집합 결과를 출력한다. 합집합시 컬럼의 없는 데이터는 NaN처리 된다.

 

 

<코드>

print("합집합")
df_merge2 = pd.merge(df1, df3, how='outer')
print(df_merge2)

 

합집합
      이름  나이    연락처       시험구분     국어     영어     수학
0     YB    30  +81-0000-0000  기말고사     100.0   100.0   100.0
1     SW    29  +81-0000-0001  기말고사      70.0    70.0    70.0
2     EJ    28  +81-0000-0002  기말고사      20.0    20.0    20.0
3     HJ    27  +81-0000-0003  기말고사      10.0    10.0    10.0
4  James    20  +81-0000-0004    NaN        NaN      NaN     NaN
5  Borwn    21  +81-0000-0005    NaN        NaN      NaN     NaN

 

 

3) how = 'left', how='right'

 

-. outer, inner 이외에 left와 right가 있다.

-. how=left or right 설정시 left는 merge함수의 왼쪽 데이터프레임 기준, right는 오른쪽 데이터 프레임 기준으로 결합

   ex) pd.merge(left, right, how='left')

 

 

<코드>

print("df1(left)을 기준으로")
df_merge_left = pd.merge(df1,df3, how = 'left')
print(df_merge_left)

print("df3(right)을 기준으로")
df_merge_left = pd.merge(df1,df3, how = 'right')
print(df_merge_left)

 

df1(left)을 기준으로

      이름  나이     연락처      시험구분   국어   영어   수학
0     YB    30  +81-0000-0000  기말고사  100.0  100.0  100.0
1     SW    29  +81-0000-0001  기말고사   70.0   70.0   70.0
2     EJ    28  +81-0000-0002  기말고사   20.0   20.0   20.0
3     HJ    27  +81-0000-0003  기말고사   10.0   10.0   10.0
4  James    20  +81-0000-0004   NaN       NaN    NaN    NaN
5  Borwn    21  +81-0000-0005   NaN       NaN    NaN    NaN


df3(right)을 기준으로

   이름  나이     연락처      시험구분   국어    영어   수학
0  YB    30  +81-0000-0000  기말고사    100    100    100
1  SW    29  +81-0000-0001  기말고사     70     70     70
2  EJ    28  +81-0000-0002  기말고사     20     20     20
3  HJ    27  +81-0000-0003  기말고사     10     10     10

 

 

3. on 파라미터 사용하기 

 

-. on 파라미터는 컬럼 또는 특정 인덱스를 기준으로 결합할 수 있다.

-. on으로 특정 컬럼을 설정하였을 경우 그 컬럼에 대한 데이터를 기준으로 모두 출력된다.

  (복수 컬럼도 가능하다. on = ["이름", "나이"]와 같이 입력)

-. 아래의 결과를 확인해보자.('이름' 컬럼을 기준으로 출력)

 

 

<코드>

#df1의 이름열을 기준으로 
print("\n")
print("df1(left)의 이름열을 기준으로")
df_merge4 = pd.merge(df1,df3, how = 'left', on="이름")
print(df_merge4)

#df3의 이름열을 기준으로 
print("\n")
print("df3(right)의 이름열을 기준으로")
df_merge5 = pd.merge(df1,df3, how = 'right', on="이름")
print(df_merge5)

 

df1(left)의 이름열을 기준으로

      이름  나이     연락처      시험구분     국어     영어     수학
0     YB    30  +81-0000-0000  기말고사    100.0   100.0    100.0
1     SW    29  +81-0000-0001  기말고사     70.0    70.0     70.0
2     EJ    28  +81-0000-0002  기말고사     20.0    20.0     20.0
3     HJ    27  +81-0000-0003  기말고사     10.0    10.0     10.0
4  James    20  +81-0000-0004    NaN        NaN     NaN      NaN
5  Borwn    21  +81-0000-0005    NaN        NaN     NaN      NaN


df3(right)의 이름열을 기준으로

   이름  나이      연락처     시험구분   국어   영어   수학
0   YB   30  +81-0000-0000  기말고사    100   100    100
1   SW   29  +81-0000-0001  기말고사     70    70     70
2   EJ   28  +81-0000-0002  기말고사     20    20     20
3   HJ   27  +81-0000-0003  기말고사     10    10     10

 

 

4. 동일한 컬럼이 있는 다른 df 합쳐보기(df2, df3)

 

-. 동일한 컬럼명이 있는 데이터프레임(중간고사,기말고사)를 합쳐보았다.

-. 결과를 보면 동일한 컬럼명이 있을 경우 자동으로 왼쪽 df는 '_x', 오른쪽 df는 '_y' 접미사가 붙여져서 출력된다.

 

 

<코드>

print("동일한 컬럼명이 있는 df 합쳐보기, 이름열을 기준")
df_merge_left = pd.merge(df2, df3, on="이름")
print(df_merge_left)

 

동일한 컬럼명이 있는 df 합쳐보기, 이름열을 기준

   이름 시험구분_x  국어_x  영어_x  수학_x 시험구분_y  국어_y  영어_y  수학_y
0  YB   중간고사   100      90    80      기말고사   100     100     100
1  YB   중간고사   100      90    80      기말고사   100     100     100
2  SW   중간고사    70      60    50      기말고사    70      70      70
3  EJ   중간고사    40       5    20      기말고사    20      20      20
4  HJ   중간고사    10       5     1      기말고사    10      10      10

 

-. x와 y대신 접미사를 별도로 설정하고 싶다면 suffixes라는 파라미터를 활용한다.

 

 

<코드>

print("suffixes 달기")
df_merge6 = pd.merge(df2, df3, on="이름", suffixes=("_중간", "_기말"))
print(df_merge6)

 

suffixes 달기

   이름 시험구분_중간  국어_중간  영어_중간  수학_중간 시험구분_기말  국어_기말  영어_기말  수학_기말
0   YB    중간고사      100        90        80      기말고사        100       100       100
1   YB    중간고사      100        90        80      기말고사        100       100       100
2   SW    중간고사       70        60        50      기말고사         70        70        70
3   EJ    중간고사       40         5        20      기말고사         20        20        20
4   HJ    중간고사       10         5         1      기말고사         10        10        10

 

 

 

5. indicator='컬럼명' : merge 사용시 합쳐지는 df에 대한 정보(출처?)

 

-. merge 사용시 합쳐진 데이터프레임 결과에서 각 데이터의 출처(left, right)를 알고 싶으면 indicator 파라미터 사용

-. 결합하는 2개 모두 데이터프레임에 있을 경우 : both

-. 왼쪽 데이터프레임(df1)에만 있을 경우 : left_only

-. 오른쪽 데이터프레임(df2)에만 있을 경우 : right_only

 

 

<코드>

print("indicator 정보")
df_merge7 = pd.merge(df1, df3, how='outer', indicator='indicator 정보')
print(df_merge7)

 

indicator 정보
      이름  나이     연락처     시험구분     국어     영어   수학   indicator 정보
0      YB   30  +81-0000-0000  기말고사    100.0   100.0  100.0         both
1      SW   29  +81-0000-0001  기말고사    70.0     70.0   70.0         both
2      EJ   28  +81-0000-0002  기말고사    20.0     20.0   20.0         both
3      HJ   27  +81-0000-0003  기말고사    10.0     10.0   10.0         both
4    James  20  +81-0000-0004    NaN       NaN      NaN    NaN    left_only
5    Borwn  21  +81-0000-0005    NaN       NaN      NaN    NaN    left_only

 

728x90