이번 포스팅에서는 pandas 모듈에서 제공하는 crosstab() 함수 에 대해서 알아 보겠습니다. crosstab 함수는 두 가지 (또는 그 이상) factor에 대한 간단한 교차표를 계산합니다. 기본적으로 factor들의 빈도표를 계산하지만, 옵션을 통하여 값을 계산할 수도 있습니다.
crosstab() 구문
crosstab() 함수의 구문은 아래와 같으며, 반환값은 교차표 형식의 데이터프레임입니다.
pandas.crosstab(
index,
columns,
values=None,
rownames=None,
colnames=None,
aggfunc=None,
margins=False,
margins_name=’All’,
dropna=True,
normalize=False
)
crosstab() 기본 구문
crosstab() 함수는 기본적으로 2 개(index, columns)의 인수(parameter)가 필요합니다.
- index: array-like, Series, or list of arrays/Series
- 행으로 그룹화할 값들을 지정합니다.
- columns : array-like, Series, or list of arrays/Series
- 칼럼으로 그룹화할 값들을 지정합니다.
기본 사용 예시
fake data를 생성한 후 crosstab 함수를 사용해 보겠습니다.
# pandas 모듈 사용을 위한 로딩
import pandas as pd
# 임시 데이터 생성
tempData = pd.DataFrame({
'gender': ['F', 'M', 'F', 'M', 'F', 'M', 'F', 'F', 'M'],
'passYn': ['pass', 'non-pass', 'pass', 'non-pass', 'pass', 'non-pass', 'pass', 'non-pass', 'pass'],
'score': [100, 70, 90, 60, 95, 50, 85, 40, 90]
})
# crosstab 기본 사용
pd.crosstab(index = tempData['gender'], columns = tempData['passYn'])
---------------------------------------------------------------------------
passYn non-pass pass
gender
F 1 4
M 3 1
crosstab 함수를 활용하여 빈도 교차표를 산출한 결과, 전체 9명 중 여성(gender = ‘F’)은 5명, 남성(gender = ‘M’)은 4명임을 알 수 있습니다. 합격(passYn = ‘pass’)자는 총 5명이고, 불합격(passYn = ‘non-pass’)자는 총 4명입니다. 여성 불합격자는 1명이고, 여성 합격자는 4명입니다. 남성 불합격자는 3명이고, 남성 합격자는 1명임을 알 수 있습니다.
만약, 수치값을 비율로 표현하고 싶다면, 어떻게 해야 할까요? normalize 옵션을 사용하여 계산할 수 있습니다. normalize 옵션을 사용하면 전체 건수 기준의 비율, 행 기준의 비율, 열 기준의 비율 모두 산출할 수 있습니다.
normalize 옵션 사용 예시
- normalize : bool, {‘all’, ‘index’, ‘columns’}, or {0,1}, default False
- 모든 값을 값의 합으로 나눈 비율 기준으로 합계를 산출합니다.
- 만약 ‘all’ 또는 True로 지정하면, 모든 값을 기준으로 비율을 산출합니다.
- ‘index’로 지정하면 각 행을 기준으로 비율을 산출합니다.
- ‘columns’로 지정하면 각 열을 기준으로 비율을 산출합니다.
# 전체 기준의 비율 산출
pd.crosstab(index = tempData['gender'], columns = tempData['passYn'], normalize = True)
----------------------------------------------------------------------------------------------
passYn non-pass pass
gender
F 0.111111 0.444444
M 0.333333 0.111111
# 각 행 기준의 비율 산출
pd.crosstab(index = tempData['gender'], columns = tempData['passYn'], normalize = 'index')
----------------------------------------------------------------------------------------------
passYn non-pass pass
gender
F 0.20 0.80
M 0.75 0.25
# 각 열 기준의 비율 산출
pd.crosstab(index = tempData['gender'], columns = tempData['passYn'], normalize = 'columns')
----------------------------------------------------------------------------------------------
passYn non-pass pass
gender
F 0.25 0.8
M 0.75 0.2
만약, 여성 불합격자 / 여성 합격자 / 남성 불합격자 / 남성 합격자 평균 점수(score)가 알고 싶으면 어떻게 해야 할까요? value와 aggfunc 옵션을 사용하여 계산할 수 있습니다.
value 및 aggfunc 옵션 사용 예시
- values : array-like, optional
- aggfunc 함수에 적용하고자 하는 변수명을 입력합니다.
- aggfunc : function, optional
- 연산하고자 하는 함수명을 입력합니다.
- values 와 aggfunc 은 항상 함께 사용해야 합니다.
# 여성 불합격자 / 여성 합격자 / 남성 불합격자 / 남성 합격자 평균 점수 산출
pd.crosstab(index = tempData['gender'], columns = tempData['passYn'],
values = tempData['score'], aggfunc = np.mean)
---------------------------------------------------------------------------
passYn non-pass pass
gender
F 40.0 92.5
M 60.0 90.0
여성/남성의 평균 점수 및 불합격/합격자의 평균 점수를 표에 표현하고 싶다면, 어떻게 해야 할까요? margins 옵션을 사용하면 됩니다.
margins 옵션 사용 예시
- margins : bool, default False
- 행과 열의 마진(소계)를 계산합니다.
pd.crosstab(index = tempData['gender'], columns = tempData['passYn'],
values = tempData['score'], aggfunc = np.mean,
margins = True)
---------------------------------------------------------------------------
passYn non-pass pass All
gender
F 40.0 92.5 82.000000
M 60.0 90.0 67.500000
All 55.0 92.0 75.555556
위의 교차표 산출 결과에서 All 대신에 다른 변수로 표현하고 싶다면, 어떻게 하면 될까요? margins_name 옵션을 사용하면 됩니다.
margins_name 옵션 사용 예시
- margins_name : str, default ‘All’
- 마진(소계)가 True일 때 들어갈 행과 열의 이름을 명시합니다.
pd.crosstab(index = tempData['gender'], columns = tempData['passYn'],
values = tempData['score'], aggfunc = np.mean,
margins = True, margins_name = 'Total')
---------------------------------------------------------------------------
passYn non-pass pass Total
gender
F 40.0 92.5 82.000000
M 60.0 90.0 67.500000
Total 55.0 92.0 75.555556
만약, 데이터의 모든 항목이 결측치(NaN)인 열을 데이터에 포함하고자 한다면, dropna = False 옵션을 사용하면 됩니다.