[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이 분석가가 설정할 수 있는 옵션이 조금 더 다양하므로 입맛에 맞게 교차분석도 하고 카이제곱검정도 하고 싶은 분은 아래 링크되어 있는 R 포스팅을 참고하세요.
- cross tabulations for R users : http://rfriend.tistory.com/120
많은 도움이 되었기를 바랍니다.
출처: https://rfriend.tistory.com/280 [R, Python 분석과 프로그래밍의 친구 (by R Friend)]