😤판다스(Pandas)에서 데이터 프레임(Data Frame)을 병합할 때 사용하는 함수는 merge가 있다.
pd.merge( ) 함수는 SQL의 JOIN과 유사하다.
pd.merge( ) 함수는 크게 세 가지로 나누어 사용할 수 있다.
- Column과 Column의 병합
- Column과 Index의 병합
- 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를 사용하는 것을 선호한다.
데이터의 양이 방대할 경우 원하는 값들만 출력하여 사용하는 것은 매우 중요하다.
데이터의 양이 많을 경우 출력과 병합의 소요되는 시간과 용량이 많이 소모될 수 있기 때문에 사용할 데이터만 추출하여 사용을 한다.
💪위 함수의 특징들을 잘 익혀서 원하는 데이터를 유용하게 추출하여 사용해보자.