[Pandas] 데이터프레임 재구조화하기(Stack,Unstack)
- Python / Pandas
- 2022. 2. 22.
pivot과 비슷하게 Series, DataFrame을 기준점에 맞게 변경하는 stack, unstack 함수 사용 방법입니다.
보통 한 묶음으로 stack, unstack을 쓰는데 그 이유는 stack은 컬럼을 인덱스로 가져오는 것이고 unstack은 인덱스를 컬럼으로 보내는 역할을 하기 때문입니다.
stack,unstack이 pivot와 다른 점이 있다면 특정 순서가 있는 인덱스에 대해서도 쓸 수 있습니다.
설명이 약간 어려운데 예로 직접 하면서 stack,unstack 방법을 살펴보겠습니다.
Stack
stack은 컬럼을 인덱스로 보내는 역할을 하는데 stack의 뜻을 보면 쌓아올린 서류더미와 같은데 이 의미와 맞추어 보면 판다스 설계자는 인덱스 추가를 쌓아올린다라고 생각하는 것 같습니다.
판다스에서의 사용방법은 간단합니다.
다음과 같은 데이터프레임을 만들겠습니다.
pgsql
import pandas as pd
df = pd.DataFrame({'col_1':[1,2]},index={'one','two'})
df

이 데이터프레임에 stack을 실행시키면 다음과 같이 컬럼이 인덱스로 옮겨지고 데이터프레임이 Series로 바뀌게 됩니다.
cpp
stack = df.stack()
stack

인덱스는 멀티인덱스가 되었습니다.
cppstack.index

인덱스의 level=0은 원래 있던 인덱스가 되고 level=1은 인덱스로 내려온 컬럼이 됩니다.
그럼 컬럼을 여러개인 경우는 어떻게 될까요??
컬럼이 여러개라도 인덱스로 변하면 모든 컬럼이 level=1로 유지가 됩니다.
reasonml
ddf = pd.DataFrame({'col_1':[1,2],'col_2':[3,4]},index={'one','two'})'
ddf

makefilestack2 = ddf.stack() stack2

axaptastack2.index

unstack
unstack은 stack과 반대로 인덱스 값을 컬럼으로 올려줍니다.
위에서 만든 데이터프레임 stack을 unstack하겠습니다.
cpp
stack.unstack()

unstack은 인덱스 level별로 컬럼을 올려줍니다.
아무 언급이 없다면 제일 level이 높은 인덱스부터 하나씩 올려줍니다.
위에서 여러 컬럼으로 한 stack2를 unstack해보면 level=1인 인덱스가 모두 컬럼으로 올라가는 걸 볼 수 있습니다.
css
stack2.unstack()

인덱스 level 2 이상
다양한 방법을 보기 위해 인덱스 level을 2로 만들겠습니다.
이전에 포스팅한 pivot에서의 예제를 이용해 진행할건데
인덱스 level=2로 만들려면 컬럼 하나가 더 있어야 해서 몇가지 추가를 더 하겠습니다.
prolog
interval = [0,0,0,1,1,1,2,2,3,3,3,4,4,4,5]
axis = ['x','y','z','x','y','z','x','y','z','x','y','z','x','y','z']
values = [0,0.5,1.0,1.5,2.0,2.5,3.0,4.0,3.5,3.0,2.5,2.1,1.5,1.7,4.0]
df = pd.DataFrame({'interval':interval,'axis':axis,'value':values})
name1 = df.copy()
name2 = df.copy()
name3 = df.copy()
name1['name'] = 'john'
name2['name'] = 'cash'
name3['name'] = 'eric'
name2['value'] *= 10
name3['value'] *= 100
all_name_df = pd.concat([name1,name2,name3])
all_name_df.set_index(['name','interval','axis'],inplace=True)
all_name_df

너무 길어서 일부만 보이지만 아무튼 name,interval,axis로 인덱스를 만들어 value만 컬럼이 되게 했습니다. 인덱스 level이 2인셈입니다.
unstack을 실행하면 다음과 같이 level=2의 인덱스인 axis가 컬럼으로 올라옵니다.
css
all_name_df.unstack()

unstack의 파라미터에 level을 지정하면 지정된 인덱스가 컬럼으로 올라갑니다.
routeros
all_name_df.unstack(level=0) # all_name_df.unstack(level='name')

여러 인덱스를 지정하고 싶다면 파라미터를 리스트로 지정합니다.
less
all_name_df.unstack(['name','interval'])

마치며..
stack은 컬럼을 인덱스로 unstack은 인덱스를 컬럼으로 체인지시키는 역할을 합니다.
하지만 stack의 경우 Series로 변환되니 염두를 해두고 코딩작업을 해야할 것 같습니다.
'Python > Pandas' 카테고리의 다른 글
[Pandas] 데이터프레임 재구조화(Melt) (0) | 2022.02.28 |
---|---|
[Pandas] 특수문자 제거하기 (0) | 2022.02.24 |
[Pandas] 데이터프레임 행(row) 추가하기 (4) | 2022.02.10 |
[Pandas] 데이터프레임 기준 컬럼 정하기(Pivoting) (0) | 2022.02.07 |
[Pandas] 함수 적용하기(map,apply, applymap) (0) | 2022.02.04 |
데이터목장님의
글이 좋았다면 응원을 보내주세요!