Python Library/Pandas

[Pandas - Python] Database-Style Dataframe Joins - merge() (데이터 베이스 병합하기)

바보1 2022. 6. 15. 21:06

두 개의 데이터 프레임을 생성해봅시다.

 

df1 = pd.DataFrame({'key': ['b', 'b', 'a', 'c', 'a', 'a', 'b'],
                    'data1': range(7)})
df2 = pd.DataFrame({'key': ['a', 'b', 'd'],
                    'data2': range(3)})
df1


        key	data1
0	b	0
1	b	1
2	a	2
3	c	3
4	a	4
5	a	5
6	b	6

df2

        key	data2
0	a	0
1	b	1
2	d	2

이때 두 개의 데이터 프레임을 병합하는 merge() 함수를 사용해봅시다.

pd.merge(df1, df2)

	key	data1	data2
0	b	0	1
1	b	1	1
2	b	6	1
3	a	2	0
4	a	4	0
5	a	5	0

어떤 column을 기준으로 병합할지 명시하지 않았지만, 알아서 두 개의 데이터 프레임에 overlapping된 컬럼을 기준으로 병합합니다.

 

만약 기준을 정해준다면,

pd.merge(df1, df2, on='key')

	key	data1	data2
0	b	0	1
1	b	1	1
2	b	6	1
3	a	2	0
4	a	4	0
5	a	5	0

위와 마찬가지로 key를 기준으로 병합합니다.

 

이때 새로운 데이터 프레임을 만들어서 병합하겠습니다.

df3 = pd.DataFrame({'lkey': ['b', 'b', 'a', 'c', 'a', 'a', 'b'],
                    'data1': range(7)})
df4 = pd.DataFrame({'rkey': ['a', 'b', 'd'],
                    'data2': range(3)})
pd.merge(df3, df4, left_on='lkey', right_on='rkey')

	lkey	data1	rkey	data2
0	b	0	b	1
1	b	1	b	1
2	b	6	b	1
3	a	2	a	0
4	a	4	a	0
5	a	5	a	0

만약 컬럼의 이름이 서로 다르다면, 하나하나 명시함으로써 분류할 수 있습니다.

 

이제는 교집합이 아닌 합집합 느낌의 merge를 사용해봅시다.

pd.merge(df1, df2, how='outer')

	key	data1	data2
0	b	0.0	1.0
1	b	1.0	1.0
2	b	6.0	1.0
3	a	2.0	0.0
4	a	4.0	0.0
5	a	5.0	0.0
6	c	3.0	NaN
7	d	NaN	2.0

알아서 없는 데이터는 NaN이 들어갑니다.

 

다시 새로운 데이터 프레임을 생성해봅시다.

df1 = pd.DataFrame({'key': ['b', 'b', 'a', 'c', 'a', 'b'],
                    'data1': range(6)})
df2 = pd.DataFrame({'key': ['a', 'b', 'a', 'b', 'd'],
                    'data2': range(5)})
df1

	key	data1
0	b	0
1	b	1
2	a	2
3	c	3
4	a	4
5	b	5
df2

	key	data2
0	a	0
1	b	1
2	a	2
3	b	3
4	d	4

이때 key를 병합 컬럼으로 하며 df1을 기준으로 병합하려면 어떻게 해야할까요?

pd.merge(df1, df2, on='key', how='left')

	key	data1	data2
0	b	0	1.0
1	b	0	3.0
2	b	1	1.0
3	b	1	3.0
4	a	2	0.0
5	a	2	2.0
6	c	3	NaN
7	a	4	0.0
8	a	4	2.0
9	b	5	1.0
10	b	5	3.0

이렇게 하면 왼쪽을 기준으로 정렬합니다.

 

만약 오른쪽 기준으로 한다면?

pd.merge(df1, df2, on='key', how='right')

	key	data1	data2
0	a	2.0	0
1	a	4.0	0
2	b	0.0	1
3	b	1.0	1
4	b	5.0	1
5	a	2.0	2
6	a	4.0	2
7	b	0.0	3
8	b	1.0	3
9	b	5.0	3
10	d	NaN	4

이렇게 됩니다.

 

만약에 교집합을 하고 싶다면,

pd.merge(df1, df2, how='inner')

	key	data1	data2
0	b	0	1
1	b	0	3
2	b	1	1
3	b	1	3
4	b	5	1
5	b	5	3
6	a	2	0
7	a	2	2
8	a	4	0
9	a	4	2

how에 inner을 넣어주면 됩니다.

 

마지막으로 한 번만 더 해보면,

left = pd.DataFrame({'key1': ['foo', 'foo', 'bar'],
                     'key2': ['one', 'two', 'one'],
                     'lval': [1, 2, 3]})
right = pd.DataFrame({'key1': ['foo', 'foo', 'bar', 'bar'],
                      'key2': ['one', 'one', 'one', 'two'],
                      'rval': [4, 5, 6, 7]})
pd.merge(left, right, on=['key1', 'key2'], how='outer')

	key1	key2	lval	rval
0	foo	one	1.0	4.0
1	foo	one	1.0	5.0
2	foo	two	2.0	NaN
3	bar	one	3.0	6.0
4	bar	two	NaN	7.0

key1, key2를 기준으로 합집합을 한 모습입니다.

 

pd.merge(left, right, on='key1')

	key1	key2_x	lval	key2_y	rval
0	foo	one	1	one	4
1	foo	one	1	one	5
2	foo	two	2	one	4
3	foo	two	2	one	5
4	bar	one	3	one	6
5	bar	one	3	two	7
pd.merge(left, right, on='key1', suffixes=('_left', '_right'))


	key1	key2_left	lval	key2_right	rval
0	foo	one	1	one	4
1	foo	one	1	one	5
2	foo	two	2	one	4
3	foo	two	2	one	5
4	bar	one	3	one	6
5	bar	one	3	two	7

좀 깨졌는데 아무튼 뒤에 접미사까지 붙여줍니다.