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

 

재구조화(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이 분석가가 설정할 수 있는 옵션이 조금 더 다양하므로 입맛에 맞게 교차분석도 하고 카이제곱검정도 하고 싶은 분은 아래 링크되어 있는 포스팅을 참고하세요. 

 

 

 

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

 

 

Posted by R Friend R_Friend

댓글을 달아 주세요