딥상어동의 딥한 생각

Pandas | Stack VS Unstack

by 딥상어동의 딥한생각

안녕하세요 신입 초보 분석가입니다. 데이터 분석을 공부하면서 고민이 됐던 내용들을 포스팅합니다.

 

github.com/GiblesDeepMind/deepPythonAnalysis

 

GiblesDeepMind/deepPythonAnalysis

I'm JDM! The man who will be the Analysis King! . Contribute to GiblesDeepMind/deepPythonAnalysis development by creating an account on GitHub.

github.com

개인 깃허브 페이지입니다.


목차

 

1. stack
2. unstack
오늘의 한마디 : stack은 위 아래로 키가 크고 unstack은 옆으로 뚱뚱해진다!

 

1. stack

stack과 unstack은 블록을 쌓고, 분해하는 것과 비슷합니다. 우선, stack을 먼저 알아봅시다.

 

sample = pd.DataFrame([['동민', '철수', '영희'], [176, 173, 160]],
                     index=['이름', '키'], columns=['조', '김', '이'])
sample

예시입니다. 참고로, 조동민은 제 이름입니다(아무도 안궁금하겠지만). 실전이 최선이다! stack을 한번 실행해봅시다.

 

sample.stack()

뭔가 이상합니다. 하지만, 이상한건 아닙니다. 이름과 키라는 인덱스를 중심으로 조/김/이라는 각 컬럼이 stack() = 쌓인게 보이시나요? 조금 더 명확하게 보죠.

sample.stack().reset_index()

index를 재정렬하니 더 명확하게 보입니다! 이름과 키 주변으로 조/김/이라는 각 컬럼이 쌓인게 보이시죠?

근데, 왜 아까는 다르게 출력되었을까요?

 

sample.stack().index.nlevels
> 2

#stack을 하기전 index 레벨
sample.index.nlevels
> 1

그건 stack을 하면서 index 레벨이 한 수준 더 높아졌기 때문입니다.

sample.stack().reset_index().index.nlevels
> 1

reset_index를 하면서 index 수준이 다시 1레벨이 되고 그에 따라 데이터 프레임으로 출력되는 것입니다.

어쨋든, 스택은 컬럼의 정보를 행에다가 쌓는 것을 말합니다. 그렇다면, stack을 하면 행이 얼마나 늘어날까요?

행의 개수 * 컬럼의 수 

만큼 늘어납니다!

 

Multiindex로 한번 더 살펴봅시다!

#lv0의 컬럼 이름이 달라야지 다르게 남는다.
col_lv2 = pd.MultiIndex.from_arrays([['주스', '주스', '빵', '빵']
                                     , ['포도주스', '사과주스',
                                       '피자빵', '소보루빵']])
index_lv2 = [['동민', '동민', '철수', '철수'],
             ['분석가', '사이언티스트', '엔지니어', '개발자']]
             
sample_lv2 = pd.DataFrame([[1, 2, 3, 4],
                           [4, 3, 2, 1],
                          [2, 4, 1, 3],
                          [3, 1, 4, 2]], index=index_lv2
                          ,columns=col_lv2)
sample_lv2

이번에도 아무말이나 적어봤습니다. 그냥, 저의 정체성도 보여주고 주스도 마시고 빵도 먹고싶었나 봅니다.

Multiindex라는건 index가 하나 초과라는 의미입니다. 

요 테이블의 경계 보이시죠? 행 index도 2층~ column도 2층으로 쌓여있습니다. 

sample_lv2.stack()

자 다시 stack을 해봅시다.

제일 아래층의 빵과 주스 종류들이 행으로 쌓인게 보이시나요? 근데, 문득 그 위층의 빵과 주스 항목으로 쌓고 싶다는 생각이 들지 않으시나요?

sample_lv2.stack(level=0)

 

그럴때는 level 파라미터를 설정해주시면 됩니다! level=-1이 디폴트 인데요. 여기서 + 1을 해주면 level=0 -> 2층의 column(빵과 주스)이 아래로 쌓이게 됩니다~ 

 

stack에는 dropna라는 파라미터가 하나 더 있는데요.

 

sample_lv3 = pd.DataFrame([[1, np.nan, 3, 4],
                           [4, 3, np.nan, 1],
                          [2, 4, 1, np.nan],
                          [np.nan, 1, 4, 2]], index=index_lv2
                          ,columns=col_lv2)
sample_lv3

sample_lv3.stack()

이렇게 위와 같이 중간중간 nan값을 섞고 다시 stack을 하면

위와 같이 아까보다 행이 더 줄어서 나옵니다. 왜냐하면, stack에는 dropna라는 파라미터가 True로 설정되기 때문인데요. Nan값은 기본적으로 drop하도록 설정되어 있습니다.

 

sample_lv3.stack(dropna=False)

dropna를 false로 설정해주면 다시 전체 행이 출력됩니다~

 

2. unstack

 

unstack은 반대로 행의 인덱스를 컬럼으로 보내는 겁니다!

쉽게 생각해서 stack은 위아래로 키가 크고 unstack은 옆으로 뚱뚱해진다고 생각하시면 될 것 같네요. 

 

sample_lv3.unstack()

 

옆으로 뚱뚱해진다는 의미를 아시겠나요? index의 맨 아래층 분석가/사이언티스트/엔지니어/개발자 항목이 모두 컬럼으로 쌓이면서 데이터 프레임이 옆으로 뚱뚱해졌습니다.

 

sample_lv3.unstack(fill_value=0)

추가적으로 unstack에는 dropna 메소드가 없습니다. 대신, fill_value=0를 사용하면 unstack으로 인해 nan이 된 값들을 채워줍니다.

 

이상, stack은 위 아래로 키가 크고 unstack은 옆으로 뚱뚱해진다! 를 기억해주시면 감사하겠습니다.

블로그의 정보

딥상어동의 딥한생각

딥상어동의 딥한생각

활동하기