Pandas crosstab() 함수 이해하기

이번 포스팅에서는 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 옵션을 사용하면 됩니다.

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다