Python Library/Pandas

[Pandas - Python] Concatenating Along an Axis - concat() (특정 열, 행을 기준으로 연결하는 법)

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

데이터 프레임, 혹은 시리즈나 numpy object를 사슬처럼 연결하는 메소드인 concatenate()와 concat()에 대해 알아봅시다.

arr = np.arange(12).reshape((3, 4))
arr

array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11]])
np.concatenate([arr, arr], axis=1)

array([[ 0,  1,  2,  3,  0,  1,  2,  3],
       [ 4,  5,  6,  7,  4,  5,  6,  7],
       [ 8,  9, 10, 11,  8,  9, 10, 11]])

보시다시피 axis = 1을 줌으로써, 열을 기준으로 합쳤습니다.

 

이제 Series에 대해서 연결해봅시다.

s1 = pd.Series([0, 1], index=['a', 'b'])
s2 = pd.Series([2, 3, 4], index=['c', 'd', 'e'])
s3 = pd.Series([5, 6], index=['f', 'g'])

pd.concat([s1, s2, s3])

a    0
b    1
c    2
d    3
e    4
f    5
g    6
dtype: int64

이쁘게 잘 연결됐네요

 

만약 이때 axis = 1로 하면 어떻게 될까요?

pd.concat([s1, s2, s3], axis=1)

	0	1	2
a	0.0	NaN	NaN
b	1.0	NaN	NaN
c	NaN	2.0	NaN
d	NaN	3.0	NaN
e	NaN	4.0	NaN
f	NaN	NaN	5.0
g	NaN	NaN	6.0

열을 기준으로 합친 모습을 볼 수 있습니다.

 

이때 s4 시리즈를 만들어봅시다.

s4 = pd.concat([s1, s3])
s4

a    0
b    1
f    5
g    6
dtype: int64
pd.concat([s1, s4], axis=1)


	0	1
a	0.0	0
b	1.0	1
f	NaN	5
g	NaN	6

axis = 1로 하니까 다시 열을 기준으로 연결했습니다.

 

교집합도 가능합니다.

pd.concat([s1, s4], axis=1, join='inner')

	0	1
a	0	0
b	1	1

 

이제 key를 주고 한 번 연결해봅시다.

result = pd.concat([s1, s1, s3], keys=['one', 'two', 'three'])
result

one    a    0
       b    1
two    a    0
       b    1
three  f    5
       g    6
dtype: int64

해당 데이터가 키에 따라서 연결되었네요

 

result.unstack()

	a	b	f	g
one	0.0	1.0	NaN	NaN
two	0.0	1.0	NaN	NaN
three	NaN	NaN	5.0	6.0

 

아무튼 만약 axis = 1로 연결한다면,

pd.concat([s1, s2, s3], axis=1, keys=['one', 'two', 'three'])

	one	two	three
a	0.0	NaN	NaN
b	1.0	NaN	NaN
c	NaN	2.0	NaN
d	NaN	3.0	NaN
e	NaN	4.0	NaN
f	NaN	NaN	5.0
g	NaN	NaN	6.0

이번엔 key가 column으로 넘어갔네요.

 

이제는 Series가 아닌 DataFrame으로 연결해봅시다.

df1 = pd.DataFrame(np.arange(6).reshape(3, 2), index=['a', 'b', 'c'],
                   columns=['one', 'two'])
df2 = pd.DataFrame(5 + np.arange(4).reshape(2, 2), index=['a', 'c'],
                   columns=['three', 'four'])
df1

	one	two
a	0	1
b	2	3
c	4	5
df2

	three	four
a	5	6
c	7	8

키를 주고 연결하면,

pd.concat([df1, df2], axis=1, keys=['level1', 'level2'])

	level1		level2
    	one	two	three	four
a	0	1	5.0	6.0
b	2	3	NaN	NaN
c	4	5	7.0	8.0

쉽죠?

 

당연한 말이지만, 딕셔너리도 가능합니다.

pd.concat({'level1': df1, 'level2': df2}, axis=1)


    	level1		level2
        one	two	three	four
a	0	1	5.0	6.0
b	2	3	NaN	NaN
c	4	5	7.0	8.0

이제 key와 column에 이름을 넣어줍시다.

사실상 계층적 인덱싱이랑 다를게 없네요

pd.concat([df1, df2], axis=1, keys=['level1', 'level2'],
          names=['upper', 'lower'])
          
          
upper	level1	level2
lower	one	two	three	four
a	0	1	5.0	6.0
b	2	3	NaN	NaN
c	4	5	7.0	8.0

 

만약 연결을 할 때, 인덱스를 무시하고 연결하고 싶다면 ignore_index = True를 하면 됩니다.

  	  a		b		c		d
0	-0.897609	1.844805	1.253168	-1.490932
1	-0.027734	1.375236	-0.025208	-0.667880
2	-2.868018	0.210689	1.287155	-0.574306
1

		b		d		a
0	0.495327	0.396050	0.588798
1	-1.281757	2.029923	-0.501945

이 두개를
pd.concat([df1, df2], ignore_index=True)

        a		b		c		d
0	-0.897609	1.844805	1.253168	-1.490932
1	-0.027734	1.375236	-0.025208	-0.667880
2	-2.868018	0.210689	1.287155	-0.574306
3	0.588798	0.495327	NaN	0.396050
4	-0.501945	-1.281757	NaN	2.029923