본문 바로가기

Python/pd. Pandas

[Python] 데이터 재구조화(reshape) : pd.crosstab() 사용해 교차표(cross tabulation)

분석을 하다 보면 원본 데이터의 구조가 분석 기법에 맞지 않아서 행과 열의 위치를 바꾼다거나, 특정 요인에 따라 집계를 해서 구조를 바꿔주어야 하는 경우가 있습니다.

 

재구조화(reshaping data)를 위해 사용할 수 있는 Python pandas의 함수들로 아래와 같이 다양한 함수가 있습니다. 

 

 - (1) pivot(), pd.pivot_table()

 - (2) stack(), unstack()

 - (3) melt()

 - (4) wide_to_long()

 - (5) pd.crosstab() 

 

 

이번 포스팅에서는 마지막으로 범주형 변수로 되어있는 요인(factors)별로 교차분석(cross tabulations) 해서, 행, 열 요인 기준 별로 빈도를 세어서 도수분포표(frequency table), 교차표(contingency table) 를 만들어주는 pd.crosstab() 에 대해서 알아보겠습니다.

 

 

 

 

 

먼저 필요한 모듈을 불러오고, 예제로 사용할 (범주형 요인 변수를 가지고 있는) 간단한 데이터셋을 생성해보겠습니다.

 



In [1]: import pandas as pd


In [2]: from pandas import DataFrame


In [3]: data = DataFrame({'id': ['id1', 'id1', 'id1', 'id2', 'id2', 'id3'],
   ...: 'fac_1': ['a', 'a', 'a', 'b', 'b', 'b'],
   ...: 'fac_2': ['d', 'd', 'd', 'c', 'c', 'd']})


In [4]: data
Out[4]:
    fac_1   fac_2    id
0     a       d       id1
1     a       d       id1
2     a       d       id1
3     b       c       id2
4     b       c       id2
5     b       d       id3




 

 

 

  (1) 교차표(contingency table, frequency table) 만들기 : pd.crosstab(index, columns)

 

pd.crosstab()의 행과 열 위치에는 array 형식의 데이터가 들어갑니다

 



# cross tabulations using pd.crosstab => contingency table
In [5]: pd.crosstab(data.fac_1, data.fac_2)
Out[5]:
fac_2  c  d
fac_1     
a      0  3
b      2  1



In [6]: pd.crosstab(data.id, data.fac_1)
Out[6]: 
fac_1  a  b
id        
id1    3  0
id2    0  2
id3    0  1



In [7]: pd.crosstab(data.id, data.fac_2)
Out[7]:
fac_2  c  d
id        
id1    0  3
id2    2  0
id3    0  1


 

 

 

  (2) Multi-index, Multi-level로 교차표 만들기 : pd.crosstab([id1, id2], [col1, col2])

 



# cross tabulations using pd.crosstab with Multi-level columns
In [8]: pd.crosstab(data.id, [data.fac_1, data.fac_2])
Out[8]:
fac_1  a  b  
fac_2  d  c  d
id           
id1    3  0  0
id2    0  2  0
id3    0  0  1





In [9]: pd.crosstab([data.fac_1, data.fac_2], data.id)
Out[9]:
id           id1  id2  id3
fac_1 fac_2              
a     d        3    0    0
b     c        0    2    0
      d        0    0    1



 

 

 

 

  (3) 교차표의 행 이름, 열 이름 부여 : pd.crosstab(rownames=['xx'], colnames=['aa'])

 



# pd.crosstab(rownames, colnames) : giving rownames, colnames
In [10]: pd.crosstab(data.id, [data.fac_1, data.fac_2],
    ...: rownames=['id_num'],
    ...: colnames=['a_b', 'c_d'])
Out[10]:
a_b     a  b  
c_d     d  c  d
id_num        
id1     3  0  0
id2     0  2  0
id3     0  0  1



 

 

 

 

  (4) 교차표의 행 합, 열 합 추가하기 : pd.crosstab(margins=True)

 



# pd.crosstab(margins=True) : adding row/column margins
In [11]: pd.crosstab(data.id, [data.fac_1, data.fac_2],
    ...: margins=True)
Out[11]:
fac_1  a  b    All
fac_2  d  c  d   
id               
id1    3  0  0   3
id2    0  2  0   2
id3    0  0  1   1
All    3  2  1   6



 

 

 

 

 

  (5) 구성비율로 교차표 만들기 : pd.crosstab(normalize=True)


# pd.corsstab(normalize=True)
# : Normalize by dividing all values by the sum of values

In [12]: pd.crosstab(data.id, [data.fac_1, data.fac_2],
    ...: normalize=True)
Out[12]:
fac_1    a         b         
fac_2    d         c         d
id                           
id1    0.5  0.000000  0.000000
id2    0.0  0.333333  0.000000
id3    0.0  0.000000  0.166667



 

 

 

 

이상으로 pd.crosstab() 을 이용한 교차표 구하기를 마치겠습니다. 

 

 

교차표는 R이나 SPSS가 깔끔하게 결과를 제시해주는 것 같고요, R이 분석가가 설정할 수 있는 옵션이 조금 더 다양하므로 입맛에 맞게 교차분석도 하고 카이제곱검정도 하고 싶은 분은 아래 링크되어 있는 포스팅을 참고하세요. 

 

 

 

많은 도움이 되었기를 바랍니다.  



출처: https://rfriend.tistory.com/280 [R, Python 분석과 프로그래밍의 친구 (by R Friend)]