Python Library/Pandas

[Pandas - Python] Reshaping with Hierarchical Indexing - stack(), unstack() (계층적 인덱싱의 구조 변환)

바보1 2022. 6. 15. 21:55
data = pd.DataFrame(np.arange(6).reshape((2, 3)),
                    index=pd.Index(['Ohio', 'Colorado'], name='state'),
                    columns=pd.Index(['one', 'two', 'three'],
                    name='number'))
data


number		one	two	three
state			
Ohio		0	1	2
Colorado	3	4	5
result = data.stack()
result

state     number
Ohio      one       0
          two       1
          three     2
Colorado  one       3
          two       4
          three     5
dtype: int32
result.unstack()


number		one	two	three
state			
Ohio		0	1	2
Colorado	3	4	5

여기까지는 지금까지 공부한 내용으로 충분히 알 수 있습니다.

 

이때 result를 다시 unstack하는 과정에서 state를 column으로 올리고 싶다면, 안에 level을 명시하면 됩니다.

result.unstack(0)

state	Ohio	Colorado
number		
one	0	3
two	1	4
three	2	5

혹은, name을 명시해도 괜찮습니다.

result.unstack('state')


state	Ohio	Colorado
number		
one	0	3
two	1	4
three	2	5

 

 

s1 = pd.Series([0, 1, 2, 3], index=['a', 'b', 'c', 'd'])
s2 = pd.Series([4, 5, 6], index=['c', 'd', 'e'])
data2 = pd.concat([s1, s2], keys=['one', 'two'])
data2

one  a    0
     b    1
     c    2
     d    3
two  c    4
     d    5
     e    6
dtype: int64

Series 두 개를 concat해봅시다.

 

data2.unstack()

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

 

data2.unstack().stack()

one  a    0.0
     b    1.0
     c    2.0
     d    3.0
two  c    4.0
     d    5.0
     e    6.0
dtype: float64

특별한 점은 없지만, unstack() -> staci()으로 갈 때 알아서 결측치는 필터링 합니다.

하지만 필터링하고 싶지 않다면,

data2.unstack().stack(dropna=False)

one  a    0.0
     b    1.0
     c    2.0
     d    3.0
     e    NaN
two  a    NaN
     b    NaN
     c    4.0
     d    5.0
     e    6.0
dtype: float64

 

다른 예시를 봅시다.

df = pd.DataFrame({'left': result, 'right': result + 5},
                  columns=pd.Index(['left', 'right'], name='side'))
df


    		side	left	right
state		number		
Ohio		one	0	5
                two	1	6
                three	2	7
Colorado	one	3	8
                two	4	9
                three	5	10

이때 state를 기준으로 unstack 한다면

df.unstack('state')

side	left			right
state	Ohio	Colorado	Ohio	Colorado
number				
one	0	3		5	8
two	1	4		6	9
three	2	5		7	10

만약 이걸 다시 side를 기준으로 stack 한다면,

df.unstack('state').stack('side')


    	state	Colorado	Ohio
number	side		
one	left	3		0
        right	8		5
two	left	4		1
        right	9		6
three	left	5		2
        right	10		7

간단하죠?