Pandas 데이터프레임 합치기(concat, merge)
15 Jul 2025 | DA개인공부 후 자료를 남기기 위한 목적임으로 내용 상에 오류가 있을 수 있습니다.
데이터프레임 합치기
다수의 데이터프레임(DataFrame) 혹은 시리즈(Series)를 결합하는 방법에 대해 정리해본다.
pd.concat() > 데이터프레임 붙이기
데이터프레임을 말그대로 물리적으로 이어붙여주는 함수 > pd.concat(데이터프레임 리스트)로 사용
import pandas as pd
# df1, df2 데이터 프레임을 각각 만들어 주면서 각각의 index를 지정해줌
df1 = pd.DataFrame({'a':['a0','a1'],
'b':['b0','b1'],
'c':['c0','c1']},
index = [0,1])
df2 = pd.DataFrame({'a':['a1','a2','a3'],
'b':['b1','b2','b3'],
'c':['c1','c2','c3'],
'd':['d1','d2','d3']},
index = [1,2,3])
df1, df2는 각각 이렇게 출력될 것이다.
[Output]
a b c
0 a0 b0 c0
1 a1 b1 c1
a b c d
1 a1 b1 c1 d1
2 a2 b2 c2 d2
3 a3 b3 c3 d3
이제 이 두 데이터프레임을 concat
을 통해 합쳐보자.
result = pd.concat([df1, df2])
result
[Output]
a b c d
0 a0 b0 c0 NaN
1 a1 b1 c1 NaN
1 a1 b1 c1 d1
2 a2 b2 c2 d2
3 a3 b3 c3 d3
pd.concat()의 axis는 디폴트 0
로 지정되어있기 때문에 둘의 합쳐진 방향이 아래로 이어붙여짐을 알 수 있다.(axis=0은 열기준, 위아래) 그리고 df1의 c는열은 존재하지 않기 때문에 c에 해당하는 데이터가 NaN
으로 채워진것 또한 볼 수 있다. 그리고 더 나아가 데이터프레임을 붙일때 그냥 이어붙이다보니 인덱스 번호도 그대로 붙여진 것을 볼 수 있다. 이때는 ignore_index=True
를 하면 인덱스 재배열이 가능하다.
- pd.concat(axis=0) 이 defalut
- 비워진 값은 NaN으로 채워짐
- 인덱스 재배열은 ignore_index=True
pd.concat(axis=1)을 하는 경우
axis=1은 행기준, 좌우방향!
result = pd.concat([df1, df2], axis=1)
result
[Output]
a b c a b c d
0 a0 b0 c0 NaN NaN NaN NaN
1 a1 b1 b1 a1 b1 c1 d1
2 NaN NaN a2 a2 b2 c2 d2
3 NaN NaN a3 a3 b3 c3 d3
이때 보면 느꼈겠지만 pd.concat()함수는 default로 outer를 가진다.
- outer: 합집합
- inner: 교집합
이때 그러면 inner옵션을 줘보도록 하자.
pd.concat(join=’inner’)을 하는 경우
result = pd.concat([df1, df2], axis=1, join='inner')
result
[Output]
a b c a b c d
1 a1 b2 c3 a1 b1 c1 d1
pd.merge() > 데이터프레임 병합
두 데이터프레임을 각 데이터에 존재하는 고유값(key)을 기준으로 병합할 때 사용(공통된 열 혹은 인덱스를 기준으로 두 테이블을 합침)
디폴트는 pd.merge(df_left, df_right, how=’inner’, on=None)이다. 예시로 위에 만들었던 데이터프레임을 다시 사용할 것이다. (이떄 on은 기준이 되는 열을 지정해주는 매개변수
를 의미)
- left, right: 병합하려는 두 데이터프레임
- on: 기준이 되는 열 이름
- how(->join): 병합 방식, 기본은 inner(교집합) outer(합집합) left(왼쪽값 기준) right(오른쪽값 기준)
- suffixes: 중복된 열 이름에 접미사 추가 (기본값: ‘_x’, ‘_y’)
좀 더 보기 편한 데이터를 가져와 예시를 들어본다.
fruit = pd.DataFrame({'Num':[123, 456, 789, 1011, 1112],
'Fruit':['Apple', 'Banana', 'Cherry', 'Lemon', 'Peach'],
'Grade':['A', 'B', 'A', 'D', 'E']})
grade = pd.DataFrame({'Num':[123, 789, 1314, 1011],
'Grade':['A', 'B', 'C', 'D']})


pd.merge() 그냥 해보는 경우
아무 옵션을 적용하지 않으면, on=None
이기에 두 데이터의 공통된 열인 Num
과 Grade
를 기준으로 교집합인 데이터가 반환된다.
result = pd.merge(fruit, grade)
result

여기서 pd.merge(fruit, grade)는 pd.merge(fruit, grade, on=[‘Num’,’Grade’])와 동일하다.
pd.merge(fruit, grade, how=’outer’)의 경우
merge()의 how는 inner(교집합)가 디폴트이기때문에 outer(합집합)인 경우를 보겠다.
result = pd.merge(fruit, grade, how='outer')
result

Grade에 존재하지 않았던 Fruit 값은 NaN
으로 들어가있음을 볼 수 있고, 공통적으로 있던 값은 하나로 합쳐져 출력된 것을 볼 수 있다.
pd.merge(fruit, grade, how=’left or right’)
- how=’left’
result = pd.merge(fruit, grade, how='left')
result

fruit에 관한것만 나오는것을 볼 수 있다. 그 이유는 pd.merge(fruit, grade, how=’left’)에서 데이터프레임의 순서가 fruit, grade 순서로 병합해준 것이기 때문이다. 따라서 왼쪽에 위치만 fruit에 관련된 데이터만 출력된 것을 볼 수 있다.
- how=’right’
result = pd.merge(fruit, grade, how='right')
result

여기서도 마찬가지로 grade에 관련된 데이터만 나왔고, 비어있는 값에 대해서는 NaN
으로 출력되어있다.
열을 지정해주는 경우
result = pd.merge(fruit, grade, on='Num')
result

공통된 열 중에 Num 하나만 지정해주는 경우 재밌는 결과가 나온다.
Num을 기준으로 Fruit 데이터가 나오고 그에 대한 fruit, grade의 Grade 데이터가 나왔다.
열을 지정해주고 합집합으로 지정한 경우
result = pd.merge(fruit, grade, on='Num', how='outer')
result

공통된 열이 아닌 열을 기준으로 지정할때
result = pd.merge(fruit, grade, on='Fruit')
result
당연히 에러가 뜬다
