Pandas는 두 개 이상의 DataFrame을 하나로 합치는 데이터 병합(merge)이나 연결(concatenate)을 지원한다.
merge
함수를 사용한 DataFrame 병합
merge
함수는 두 데이터프레임의 공통 열 혹은 인덱스를 기준으로 두 개의 테이블을 합친다. 이 때 기준이 되는 열, 행의 데이터를 키(Key)라고 한다.
import pandas as pd
df1 = pd.DataFrame({
'고객번호' : [ 1001 , 1002 , 1003 , 1004 , 1005 , 1006 , 1007 ],
'이름' : [ '둘리' , '도우너' , '또치' , '길동' , '마이콜' , '희동' , '영희' ]
}, columns = [ '고객번호' , '이름' ])
df1
인덱스 고객번호 이름 0 1001 둘리 1 1002 도우너 2 1003 또치 3 1004 길동 4 1005 마이콜 5 1006 희동 6 1007 영희
df2 = pd.DataFrame({
'고객번호' : [ 1001 , 1001 , 1005 , 1006 , 1008 , 1001 ],
'금액' : [ 10000 , 20000 , 15000 , 5000 , 100000 , 30000 ]
}, columns = [ '고객번호' , '금액' ])
df2
인덱스 고객번호 금액 0 1001 10000 1 1001 20000 2 1005 15000 3 1006 5000 4 1008 100000 5 1001 30000
merge
함수로 위의 두 데이터프레임 df1, df2 를 합치면 공통열인 고객번호
열을 기준으로 데이터를 찾아서 합친다. 이 때 기본적으로는 양쪽 데이터프레임에 모두 키가 존재하는 데이터만 보여주는 inner join 방식을 사용한다.
pd.merge(df1, df2)
인덱스 고객번호 이름 금액 0 1001 둘리 10000 1 1001 둘리 20000 2 1001 둘리 30000 3 1005 마이콜 15000 4 1006 희동 5000
outer join 방식은 키 값이 한쪽에만 있어도 데이터를 보여준다.
pd.merge(df1, df2, how = 'outer' )
인덱스 고객번호 이름 금액 0 1001 둘리 10000.0 1 1001 둘리 20000.0 2 1001 둘리 30000.0 3 1002 도우너 NaN 4 1003 또치 NaN 5 1004 길동 NaN 6 1005 마이콜 15000.0 7 1006 희동 5000.0 8 1007 영희 NaN 9 1008 NaN 100000.0
left, right 방식은 각각 첫번째, 혹은 두번째 데이터프레임의 키 앖을 모두 보여준다.
pd.merge(df1, df2, how = 'left' )
인덱스 고객번호 이름 금액 0 1001 둘리 10000.0 1 1001 둘리 20000.0 2 1001 둘리 30000.0 3 1002 도우너 NaN 4 1003 또치 NaN 5 1004 길동 NaN 6 1005 마이콜 15000.0 7 1006 희동 5000.0 8 1007 영희 NaN
pd.merge(df1, df2, how = 'right' )
고객번호 이름 금액 0 1001 둘리 10000 1 1001 둘리 20000 2 1001 둘리 30000 3 1005 마이콜 15000 4 1006 희동 5000 5 1008 NaN 100000
만약 테이블에 키 값이 같은 데이터가 여러개 있는 경우에는 있을 수 있는 모든 경우의 수를 따져서 조합을 만들어 낸다.
df1 = pd.DataFrame({
'품종' : [ 'setosa' , 'setosa' , 'virginica' , 'virginica' ],
'꽃잎길이' : [ 1.4 , 1.3 , 1.5 , 1.3 ]
}, columns = [ '품종' , '꽃잎길이' ])
df1
품종 꽃잎길이 0 setosa 1.4 1 setosa 1.3 2 virginica 1.5 3 virginica 1.3
df2 = pd.DataFrame({
'품종' : [ 'setosa' , 'virginica' , 'virginica' , 'versicolor' ],
'꽃잎너비' : [ 0.4 , 0.3 , 0.5 , 0.3 ]},
columns = [ '품종' , '꽃잎너비' ])
df2
품종 꽃잎너비 0 setosa 0.4 1 virginica 0.3 2 virginica 0.5 3 versicolor 0.3
이 데이터에서 키 값 setosa에 대해 왼쪽 데이터프레임에는 1.4와 1.3 이라는 2개의 데이터, 오른쪽 데이터프레임에는 0.4라는 1개의 데이터가 있으므로 병합된 데이터에는 setosa가 (1.4, 0.4), (1.3, 0.4) 두 개의 데이터가 생긴다. 키값 virginica의 경우에는 왼쪽 데이터프레임에 1.5와 1.3이라는 2개의 데이터, 오른쪽 데이터프레임에 0.3와 0.5라는 2개의 데이터가 있으므로 2개와 2개의 조합에 의해 4가지 값이 생긴다.
pd.merge(df1, df2)
품종 꽃잎길이 꽃잎너비 0 setosa 1.4 0.4 1 setosa 1.3 0.4 2 virginica 1.5 0.3 3 virginica 1.5 0.5 4 virginica 1.3 0.3 5 virginica 1.3 0.5
두 데이터프레임에서 이름이 같은 열은 모두 키가 된다. 만약 이름이 같아도 키가 되면 안되는 열이 있다면 on
인수로 기준열을 명시해야 한다. 다음 예에서 첫번째 데이터프레임의 데이터 는 실제로는 금액을 나타내는 데이터 이고 두번째 데이터프레임의 데이터 는 실제로 성별을 나타내는 데이터이므로 이름이 같아도 다른 데이터이다. 따라서 이 열은 기준열이 되면 안된다.
df1 = pd.DataFrame({
'고객명' : [ '춘향' , '춘향' , '몽룡' ],
'날짜' : [ '2018-01-01' , '2018-01-02' , '2018-01-01' ],
'데이터' : [ '20000' , '30000' , '100000' ]})
df1
고객명 날짜 데이터 0 춘향 2018-01-01 20000 1 춘향 2018-01-02 30000 2 몽룡 2018-01-01 100000
df2 = pd.DataFrame({
'고객명' : [ '춘향' , '몽룡' ],
'데이터' : [ '여자' , '남자' ]})
df2
pd.merge(df1, df2, on = '고객명' )
고객명 날짜 데이터_x 데이터_y 0 춘향 2018-01-01 20000 여자 1 춘향 2018-01-02 30000 여자 2 몽룡 2018-01-01 100000 남자
이 때 기준 열이 아니면서 이름이 같은 열에는 _x
또는 _y
와 같은 접미사가 붙는다.
반대로 키가 되는 기준열의 이름이 두 데이터프레임에서 다르면 left_on
, right_on
인수를 사용하여 기준열을 명시해야 한다.
df1 = pd.DataFrame({
'이름' : [ '영희' , '철수' , '철수' ],
'성정' : [ 1 , 2 , 3 ]
})
df1
df2 = pd.DataFrame({
'성명' : [ '영희' , '영희' , '철수' ],
'성적2' : [ 4 , 5 , 6 ]})
df2
pd.merge(df1, df2, left_on = '이름' , right_on = '성명' )
이름 성정 성명 성적2 0 영희 1 영희 4 1 영희 1 영희 5 2 철수 2 철수 6 3 철수 3 철수 6
일반 데이터 열이 아닌 인덱스를 기준열로 사용하여면 left_index
또는 right_index
인수를 True
로 설정한다.
df1 = pd.DataFrame({
'도시' : [ '서울' , '서울' , '서울' , '부산' , '부산' ],
'연도' : [ 2000 , 2005 , 2010 , 2000 , 2005 ],
'인구' : [ 9853972 , 9762546 , 9631482 , 3655437 , 3512547 ]})
df1
도시 연도 인구 0 서울 2000 9853972 1 서울 2005 9762546 2 서울 2010 9631482 3 부산 2000 3655437 4 부산 2005 3512547
import numpy as np
df2 = pd.DataFrame(
np.arange( 12 ).reshape(( 6 , 2 )),
index = [[ '부산' , '부산' , '서울' , '서울' , '서울' , '서울' ],
[ 2000 , 2005 , 2000 , 2005 , 2010 , 2015 ]],
columns = [ '데이터1' , '데이터2' ])
df2
데이터1 데이터2 부산 2000 0 1 부산 2005 2 3 서울 2000 4 5 서울 2005 6 7 서울 2010 8 9 서울 2015 10 11
pd.merge(df1, df2, left_on = [ '도시' , '연도' ], right_index = True )
도시 연도 인구 데이터1 데이터2 0 서울 2000 9853972 4 5 1 서울 2005 9762546 6 7 2 서울 2010 9631482 8 9 3 부산 2000 3655437 0 1 4 부산 2005 3512547 2 3
df1 = pd.DataFrame(
[[ 1 ., 2 .], [ 3 ., 4 .], [ 5 ., 6 .]],
index = [ 'a' , 'c' , 'e' ],
columns = [ '서울' , '부산' ])
df1
서울 부산 a 1.0 2.0 c 3.0 4.0 e 5.0 6.0
df2 = pd.DataFrame(
[[ 7 ., 8 .], [ 9 ., 10 .], [ 11 ., 12 .], [ 13 , 14 ]],
index = [ 'b' , 'c' , 'd' , 'e' ],
columns = [ '대구' , '광주' ])
df2
대구 광주 b 7.0 8.0 c 9.0 10.0 d 11.0 12.0 e 13.0 14.0
pd.merge(df1, df2, how = 'outer' , left_index = True , right_index = True )
서울 부산 대구 광주 a 1.0 2.0 NaN NaN b NaN NaN 7.0 8.0 c 3.0 4.0 9.0 10.0 d NaN NaN 11.0 12.0 e 5.0 6.0 13.0 14.0
join 매서드
merge
명령어 대신 join
매서드를 사용할 수도 있다.
df1.join(df2, how = 'outer' )
서울 부산 대구 광주 a 1.0 2.0 NaN NaN b NaN NaN 7.0 8.0 c 3.0 4.0 9.0 10.0 d NaN NaN 11.0 12.0 e 5.0 6.0 13.0 14.0
concat
함수를 사용한 데이터 연결
concat
함수를 사용하면 기준 열(key column)을 사용하지 않고 단순히 데이터를 연결(concatenate)한다.
기본적으로는 위/아래로 데이터 행을 연결한다. 단순히 두 시리즈나 데이터프레임을 연결하기 때문에 인덱스 값이 중복될 수 있다.
s1 = pd.Series([ 0 , 1 ], index = [ 'A' , 'B' ])
s2 = pd.Series([ 2 , 3 , 4 ], index = [ 'A' , 'B' , 'C' ])
s1
A 0
B 1
dtype: int64
s2
A 2
B 3
C 4
dtype: int64
pd.concat([s1, s2])
A 0
B 1
A 2
B 3
C 4
dtype: int64
내부적으로 기본값은 axis=0
이기 때문에 만약 옆으로 데이터 열을 연결하고 싶으면 axis=1
로 인수를 설정한다.
df1 = pd.DataFrame(
np.arange( 6 ).reshape( 3 , 2 ),
index = [ 'a' , 'b' , 'c' ],
columns = [ '데이터1' , '데이터2' ])
df1
df2 = pd.DataFrame(
5 + np.arange( 4 ).reshape( 2 , 2 ),
index = [ 'a' , 'c' ],
columns = [ '데이터3' , '데이터4' ])
df2
pd.concat([df1, df2], axis = 1 )
데이터1 데이터2 데이터3 데이터4 a 0 1 5.0 6.0 b 2 3 NaN NaN c 4 5 7.0 8.0
출처 : 데이터사이언스 스쿨(http://datascienceschool.net )