Back-End/Pandas

merge

pshoon25 2022. 12. 18. 19:38

😤판다스(Pandas)에서 데이터 프레임(Data Frame)을 병합할 때 사용하는 함수는 merge가 있다.

 

pd.merge( ) 함수는 SQL의 JOIN과 유사하다.

pd.merge( ) 함수는 크게 세 가지로 나누어 사용할 수 있다.

  1. Column과 Column의 병합
  2. Column과 Index의 병합
  3. Index와 Index의 병합

하나씩 순서대로 알아보자 !


1. Column과 Column의 병합

pd.merge( )함수의 특징은 Inner Join, Outer Join 두 개로 나눌 수 있다.

  • Inner Join : 공통되는 값의 행만 병합하여 하나의 데이터 프레임으로 출력
  • Outer Join : 공통되는 값의 행과 공통되지 않는 값의 행까지  병합하여 하나의 데이터 프레임으로 출력

글로는 설명이 어려우니, 이미지를 포함하여 아래에서 같이 설명하겠다.


Inner Join

두 데이터 프레임 간의 지정한 컬럼 중의 공통되는 값을 기준으로 해당 행을 모두 출력하여 하나의 데이터 프레임으로 반환한다.

 

Inner Join에서도 두 개의 특징으로 나눌 수 있다.

  • 공통되는 컬럼이 있는경우
  • 공통되는 컬럼이 없는 경우

 

👉우선, 공통되는 컬럼이 있을 경우의 pd.merge( ) 함수의 구조는 아래와 같다.

df = pd.merge(df1, df2, on='컬럼명', how='inner')

 

파라미터의 on='컬럼명'에 각 df1, df2의 공통되는 컬럼을 지정해주어 사용할 수 있다.

 

표를 그려 설명하자면 아래와 같다.

 

아래와 같이 두개의 데이터 프레임 df1, df2가 있다.

df = pd.merge(df1, df2, on='c1') 를 입력할 경우,

df1과 df2의 공통되는 컬럼  'c1'을 기준으로 병합한다.

 

df1과 df2의 c1의 공통되는 값은 a, b 값이다.

df1['c1']의 a, b가 있는 전체 행 값

df2['c1']의 a, b가 있는 전체 행 값 

두 값이 합쳐져 하나의 데이터 프레임으로 생성된다.

단, 공통되는 부분 c1의 a, b는 중복으로 반환되지 않는다.

*원하는 데이터 프레임의 시리즈(Series)만 지정하여 출력도 가능하다.

import numpy as np
import pandas as pd

df1 = pd.DataFrame({'c1': [3, 4, 'a', 'b'],
                    'c2': [11, 22, 33, 44],
                    'c3': [10, 20, 30, 40]})
df2 = pd.DataFrame({'c1': ['a', 'b', 'c', 'd'],
                    'd1': ['aa', 'bb', 'cc', 'dd'],
                    'd2': ['aaa', 'bbb', 'ccc', 'ddd']})
print(df1)
'''
  c1  c2  c3
0  3  11  10
1  4  22  20
2  a  33  30
3  b  44  40
'''
print(df2)
'''
  c1  d1   d2
0  a  aa  aaa
1  b  bb  bbb
2  c  cc  ccc
3  d  dd  ddd
'''
# 전체 컬럼 출력
df = pd.merge(df1, df2, on='c1', how='inner')
print(df)
'''
  c1  c2  c3  d1   d2
0  a  33  30  aa  aaa
1  b  44  40  bb  bbb
'''
# 원하는 컬럼만 출력
df = pd.merge(df1[['c1', 'c3']], df2[['c1', 'd1']], on='c1', how='inner')
print(df)
'''
  c1  c3  d1
0  a  30  aa
1  b  40  bb
'''

 

👉공통되는 컬럼이 없을 경우의 pd.merge( ) 함수의 구조는 아래와 같다.

df = pd.merge(df1, df2, left_on='df1 컬럼명', right_on='df2 컬럼명', how='inner')

 

pd.merge( )의 파라미터 중 on='컬럼명' 대신 left_on='df1 컬럼명', right_on='df2 컬럼명' 파라미터를 입력하면 된다.

 

단, 컬럼명이 공통되지 않으니 'c1'과 'd1'이 모두 출력된다.

import numpy as np
import pandas as pd

df1 = pd.DataFrame({'c1': [3, 4, 'a', 'b'],
                    'c2': [11, 22, 33, 44],
                    'c3': [10, 20, 30, 40]})
df2 = pd.DataFrame({'d1': ['a', 'b', 'c', 'd'],
                    'd2': ['aa', 'bb', 'cc', 'dd'],
                    'd3': ['aaa', 'bbb', 'ccc', 'ddd']})

df = pd.merge(df1, df2, left_on='c1', right_on='d1', how='inner')
print(df)
'''
  c1  c2  c3 d1  d2   d3
0  a  33  30  a  aa  aaa
1  b  44  40  b  bb  bbb
'''

Outer Join

두 데이터 프레임 간의 지정한 컬럼 중의 공통되는 값과 공통되지 않는 값의 해당 행을 모두 출력하여 하나의 데이터 프레임으로 반환한다.

 

Outer Join에서도 위와 동일하게 두 개의 특징으로 나눌 수 있다.

  • 공통되는 컬럼이 있는경우
  • 공통되는 컬럼이 없는 경우

또한, df1 또는 df2의 데이터 프레임 중에서 하나를 선택하여 해당 컬럼에만 공통되지 않은 값까지 반환할 수 있다.

 

우선, 공통되는 컬럼이 있을 경우의 pd.merge( ) 함수의 구조는 아래와 같다.

df = pd.merge(df1, df2, on='컬럼명', how='outer'|'left'|'right')

 

👉df = pd.merge(df1, df2, on='컬럼명', how='outer')일 경우,

두 개의 데이터 프레임 df1, df2의 공통 컬럼의 c1의 공통되는 값 a, b를 기준으로 병합된다. 

단, 값이 일치하지 않는 행들은 Null 값으로 채워져 반환된다.

import numpy as np
import pandas as pd

df1 = pd.DataFrame({'c1': [3, 4, 'a', 'b'],
                    'c2': [11, 22, 33, 44],
                    'c3': [10, 20, 30, 40]})
df2 = pd.DataFrame({'c1': ['a', 'b', 'c', 'd'],
                    'd2': ['aa', 'bb', 'cc', 'dd'],
                    'd3': ['aaa', 'bbb', 'ccc', 'ddd']})

df = pd.merge(df1, df2, on='c1', how='outer')
print(df)
'''
  c1    c2    c3   d2   d3
0  3  11.0  10.0  NaN  NaN
1  4  22.0  20.0  NaN  NaN
2  a  33.0  30.0   aa  aaa
3  b  44.0  40.0   bb  bbb
4  c   NaN   NaN   cc  ccc
5  d   NaN   NaN   dd  ddd
'''

 

👉df = pd.merge(df1, df2, on='컬럼명', how='left')일 경우,

how = left일 경우 df1을 지정하며, 

df1의 일치하는 값 a, b의 행 값과 일치하지 않는 값 3, 4의 행 값은 모두 출력하며, df2의 값은 Null 값으로 채워져 반환된다.

다만, df2의 일치하지 않는 값 c, d의 행 값은 출력되지 않는다.

import numpy as np
import pandas as pd

df1 = pd.DataFrame({'c1': [3, 4, 'a', 'b'],
                    'c2': [11, 22, 33, 44],
                    'c3': [10, 20, 30, 40]})
df2 = pd.DataFrame({'c1': ['a', 'b', 'c', 'd'],
                    'd2': ['aa', 'bb', 'cc', 'dd'],
                    'd3': ['aaa', 'bbb', 'ccc', 'ddd']})

df = pd.merge(df1, df2, on='c1', how='outer')
print(df)
'''
  c1    c2    c3   d2   d3
0  3  11.0  10.0  NaN  NaN
1  4  22.0  20.0  NaN  NaN
2  a  33.0  30.0   aa  aaa
3  b  44.0  40.0   bb  bbb
4  c   NaN   NaN   cc  ccc
5  d   NaN   NaN   dd  ddd
'''

df = pd.merge(df1, df2, on='c1', how='left')
print(df)
'''
  c1  c2  c3   d2   d3
0  3  11  10  NaN  NaN
1  4  22  20  NaN  NaN
2  a  33  30   aa  aaa
3  b  44  40   bb  bbb
'''
df = pd.merge(df1, df2, on='c1', how='right')
print(df)
'''
  c1    c2    c3  d2   d3
0  a  33.0  30.0  aa  aaa
1  b  44.0  40.0  bb  bbb
2  c   NaN   NaN  cc  ccc
3  d   NaN   NaN  dd  ddd
'''

 

👉공통되는 컬럼이 없을 경우의 pd.merge( ) 함수의 구조는 아래와 같다.

df = pd.merge(df1, df2, left_on='df1 컬럼명', right_on='df2 컬럼명', how='outer')

특징은 위의 함수들과 동일하다.

import numpy as np
import pandas as pd

df1 = pd.DataFrame({'c1': [3, 4, 'a', 'b'],
                    'c2': [11, 22, 33, 44],
                    'c3': [10, 20, 30, 40]})
df2 = pd.DataFrame({'d1': ['a', 'b', 'c', 'd'],
                    'd2': ['aa', 'bb', 'cc', 'dd'],
                    'd3': ['aaa', 'bbb', 'ccc', 'ddd']})

df = pd.merge(df1, df2, left_on='c1', right_on='d1', how='outer')
print(df)
'''
    c1    c2    c3   d1   d2   d3
0    3  11.0  10.0  NaN  NaN  NaN
1    4  22.0  20.0  NaN  NaN  NaN
2    a  33.0  30.0    a   aa  aaa
3    b  44.0  40.0    b   bb  bbb
4  NaN   NaN   NaN    c   cc  ccc
5  NaN   NaN   NaN    d   dd  ddd
'''

df = pd.merge(df1, df2, left_on='c1', right_on='d1', how='left')
print(df)
'''
  c1  c2  c3   d1   d2   d3
0  3  11  10  NaN  NaN  NaN
1  4  22  20  NaN  NaN  NaN
2  a  33  30    a   aa  aaa
3  b  44  40    b   bb  bbb
'''
df = pd.merge(df1, df2, left_on='c1', right_on='d1', how='right')
print(df)
'''
    c1    c2    c3 d1  d2   d3
0    a  33.0  30.0  a  aa  aaa
1    b  44.0  40.0  b  bb  bbb
2  NaN   NaN   NaN  c  cc  ccc
3  NaN   NaN   NaN  d  dd  ddd
'''

위에서는 지금까지 컬럼과 컬럼의 병합을 알아보았다.

 

아래에서는 컬럼과 인덱스, 인덱스와 인덱스의 병합까지 알아보려 한다.

 

2. Column과 Index의 병합

 

👉컬럼과 인덱스의 병합의 기본 구조는 아래와 같다.

df = pd.merge(df1, df2, left_on='df1 컬럼명', right_on=df2.index)

또는

df = pd.merge(df1, df2, left_on='df1 컬럼명', right_index=True)

df1의 시리즈의 값 중에서 df2의 인덱스 값과 동일한 컬럼이 존재할 경우,

df1 에는 left_on='컬럼명'을 기재하고, df2 에는 right_on=df2.index 또는 right+index=True 를 입력해주면 된다.

 

표를 그려 설명하자면 아래와 같다.

df1의 시리즈의 값들 중 df2의 인덱스와 동일한 값이 있을 경우,

left_on='df1의 컬럼명'을 입력

right_on=df2.index 또는 right_index=True 를 입력한다.

그러면 df1의 'c1' 시리즈 중 df2의 인덱스 값과 일치하는 C, D의 값의 행을 모두 출력한다.

import numpy as np
import pandas as pd

df1 = pd.DataFrame({'c1': ['A', 'B', 'C', 'D'],
                    'c2': [11, 22, 33, 44],
                    'c3': [10, 20, 30, 40]})
df2 = pd.DataFrame({'d1': ['a', 'b', 'c', 'd'],
                    'd2': ['aa', 'bb', 'cc', 'dd'],
                    'd3': ['aaa', 'bbb', 'ccc', 'ddd']}, index=list('CDEF'))
print(df1)
'''
  c1  c2  c3
0  A  11  10
1  B  22  20
2  C  33  30
3  D  44  40
'''
print(df2)
'''
  d1  d2   d3
C  a  aa  aaa
D  b  bb  bbb
E  c  cc  ccc
F  d  dd  ddd
'''
df = pd.merge(df1, df2, left_on='c1', right_on=df2.index)
print(df)
'''
  c1  c2  c3 d1  d2   d3
0  C  33  30  a  aa  aaa
1  D  44  40  b  bb  bbb
'''
df = pd.merge(df1, df2, left_on='c1', right_index=True)
print(df)
'''
  c1  c2  c3 d1  d2   d3
2  C  33  30  a  aa  aaa
3  D  44  40  b  bb  bbb
'''

3. Index와 Index의 병합

인덱스와 인덱스의 병합은 컬럼과 인덱스의 병합과 유사하다.

컬럼을 입력하는 위치에 인덱스를 입력하면 된다.

 

👉인덱스와 인덱스의 병합의 사용되는 파라미터의 기본 구조는 아래와 같다.

df = pd.merge(df1, df2, left_on=df1.index, right_on=df2.index)

또는

df = pd.merge(df1, df2, left_index=True, right_index=True)

물론, 두 개를 혼합하여 이용할 수 있다.

 

표로 설명하자면 아래와 같다.

df1의 인덱스의 df2의 인덱스 중 일치하는 인덱스 명을 기준으로 병합한다.

import numpy as np
import pandas as pd

df1 = pd.DataFrame({'c1': [1, 2, 3, 4],
                    'c2': [11, 22, 33, 44],
                    'c3': [10, 20, 30, 40]}, index=list('ABCD'))
df2 = pd.DataFrame({'d1': ['a', 'b', 'c', 'd'],
                    'd2': ['aa', 'bb', 'cc', 'dd'],
                    'd3': ['aaa', 'bbb', 'ccc', 'ddd']}, index=list('CDEF'))
print(df1)
'''
   c1  c2  c3
A   1  11  10
B   2  22  20
C   3  33  30
D   4  44  40
'''
print(df2)
'''
  d1  d2   d3
C  a  aa  aaa
D  b  bb  bbb
E  c  cc  ccc
F  d  dd  ddd
'''
df = pd.merge(df1, df2, left_on=df1.index, right_index=True)
print(df)
'''
  key_0  c1  c2  c3 d1  d2   d3
C     C   3  33  30  a  aa  aaa
D     D   4  44  40  b  bb  bbb
'''
df = pd.merge(df1, df2, left_index=True, right_index=True)
print(df)
'''
   c1  c2  c3 d1  d2   d3
C   3  33  30  a  aa  aaa
D   4  44  40  b  bb  bbb
'''

left_on=, right_on=을 이용할 경우,

병합하여 출력한 데이터 프레임의 key_0이라는 컬럼이 추가되어 출력된다.

 

left_index=True, right_index=True를 이용할 경우,

병합하여 출력한 데이터에는 순수 값들로만 출력된다.

 

그래서 나는 개인적으로 _index=True를 사용하는 것을 선호한다.


데이터의 양이 방대할 경우 원하는 값들만 출력하여 사용하는 것은 매우 중요하다.

 

데이터의 양이 많을 경우 출력과 병합의 소요되는 시간과 용량이 많이 소모될 수 있기 때문에 사용할 데이터만 추출하여 사용을 한다.

 

💪위 함수의 특징들을 잘 익혀서 원하는 데이터를 유용하게 추출하여 사용해보자.

'Back-End > Pandas' 카테고리의 다른 글

Group by  (0) 2022.12.19
sort  (0) 2022.12.16
"Null"  (0) 2022.12.16
추가, 삽입, 삭제  (0) 2022.12.15
Subset  (0) 2022.12.14