데이터 분석/강의 노트

Pandas: 통계량 알아보기, 그룹화하기, 범주별 비율 구하기

hyunseo 2024. 7. 10. 21:22

분포와 통계량

discribe() 함수를 사용하면 다양한 기술통계량을 한 번에 확인할 수 있습니다. 역시 타이타닉 데이터셋을 가지고 기초통계량을 살펴보겠습니다.

import pandas as pd

file_path = './data/titanic_train.csv'
df = pd.read_csv(file_path)

df.describe()

 

  PassengerId Survived Pclass Age SibSp Parch Fare
count 891.000000 891.000000 891.000000 714.000000 891.000000 891.000000 891.000000
mean 446.000000 0.383838 2.308642 29.699118 0.523008 0.381594 32.204208
std 257.353842 0.486592 0.836071 14.526497 1.102743 0.806057 49.693429
min 1.000000 0.000000 1.000000 0.420000 0.000000 0.000000 0.000000
25% 223.500000 0.000000 2.000000 20.125000 0.000000 0.000000 7.910400
50% 446.000000 0.000000 3.000000 28.000000 0.000000 0.000000 14.454200
75% 668.500000 1.000000 3.000000 38.000000 1.000000 0.000000 31.000000
max 891.000000 1.000000 3.000000 80.000000 8.000000 6.000000 512.329200

 

대푯값

또한, 여러 가지 함수를 이용해서 대푯값을 구할 수 있습니다. 주의할 점은, 데이터 값이 문자열일 경우 대푯값을 구할 수 없기 때문에 숫자형 데이터만 계산하도록 옵션을 추가해 주어야 합니다. 각 함수에 numeric_only=True를 인자로 전달합니다.

 

메소드 설명
min() 최솟값
max() 최댓값
mean() 평균
median() 중간값
std() 표준편차
var() 분산
quantile() 분위수

 

df.mean(numeric_only=True)
# PassengerId    446.0000
# Survived         0.0000
# Pclass           3.0000
# Age             28.0000
# SibSp            0.0000
# Parch            0.0000
# Fare            14.4542
# dtype: float64

 

분위수를 나타내주는 quantile() 함수 같은 경우에는 백분율도 같이 입력해 주어야 합니다.

 

df.quantile(0.5, numeric_only=True)
# PassengerId    446.0000
# Survived         0.0000
# Pclass           3.0000
# Age             28.0000
# SibSp            0.0000
# Parch            0.0000
# Fare            14.4542
# Name: 0.5, dtype: float64

 

변수와의 상관관계 파악하기

엑셀 수업에서 상관분석을 했었습니다. corr() 함수를 사용하면 pandas로도 상관분석이 가능합니다.

 

df.corr(numeric_only=True)

 

  PassengerId Survived Pclass Age SibSp Parch   Fare
PassengerId 1.000000 -0.005007 -0.035144 0.036847 -0.057527 -0.001652 PassengerId 0.012658
Survived -0.005007 1.000000 -0.338481 -0.077221 -0.035322 0.081629 Survived 0.257307
Pclass -0.035144 -0.338481 1.000000 -0.369226 0.083081 0.018443 Pclass -0.549500
Age 0.036847 -0.077221 -0.369226 1.000000 -0.308247 -0.189119 Age 0.096067
SibSp -0.057527 -0.035322 0.083081 -0.308247 1.000000 0.414838 SibSp 0.159651
Parch -0.001652 0.081629 0.018443 -0.189119 0.414838 1.000000 Parch 0.216225
Fare 0.012658 0.257307 -0.549500 0.096067 0.159651 0.216225 Fare 1.000000

 

데이터 그룹화하기 - group by

groupby() 함수를 사용하면 같은 값을 한 그룹으로 묶어서 여러 가지 연산 및 통계를 구할 수 있습니다.

 

함수 설명
count() 행의 갯수
nunique() 행의 유니크한 갯수
sum()
mean() 평균
min() 최솟값
max() 최댓값
std() 표준편차
var() 분산

 

아래의 컬럼을 가지는 NBA 선수 데이터가 있다고 합시다. 이 중에서 선수들을 포지션(Position) 별로 묶어서 기초 통계량을 확인해 보겠습니다.

Index(['Name', 'Team', 'Number', 'Position', 'Age', 'Height', 'Weight',
       'College', 'Salary'],
      dtype='object')

 

groupby()를 통해 포지션을 기준으로 데이터를 그룹화한 다음, 각 컬럼의 평균을 구해보겠습니다. groupby에서도 역시 문자열은 통계량을 계산할 수 없기 때문에 nuemeric_only를 통해 문자열을 값으로 가지는 컬럼은 제외시켜 줍니다.

 

nba.groupby('Position').mean(numeric_only=True)

 

평균 급여(Salary)의 평균만 알고 싶다면 데이터를 포지션을 기준으로 그룹화한 다음 Salary 칼럼을 선택하고 평균을 구하면 됩니다. groupby() 정렬 기능이 없기 때문에 sort_values() 함수를 이용해서 데이터를 정렬시켜 줍니다.

 

nba.groupby('Position')['Salary'].mean().round().sort_values()
# Position
# SG    4009861.0
# PF    4562483.0
# SF    4857393.0
# PG    5077829.0
# C     5967052.0
# Name: Salary, dtype: float64

 

crosstab

crosstab() 함수롤 사용하면 범주형 데이터를 비교분석할 때 유용합니다. 예시로, 성별과 생존 여부를 분석해보겠습니다.

pd.crosstab(df['Sex'], df['Survived'])

 

Survived 0 1
Sex    
female 81 233
male 468 109

 

위의 표를 통해, 사망한 남성이 468명으로 가장 많은 수를 차지하는 것을 알 수 있습니다. 이를 숫자가 아니라 비율로 보고 싶다면 어떻게 할까요?

 

범주별 비율 구하기

crosstab() 함수에 normalize라는 옵션을 추가하여 범주별 비율을 구할 수 있습니다.

  • all : crosstab()을 통해 비교하는 모든 데이터의 합이 1이 됩니다.
  • index : crosstab()을 통해 비교하는 각 행의 데이터 합이 1이 됩니다.
  • columns : crosstab()을 통해 비교하는 각 열의 데이터 합이 1이 됩니다.

 

pd.crosstab(df['Sex'], df['Survived'], normalize='all', margins=True)

 

Survived 0 1 All
Sex      
female 0.090909 0.261504 0.352413
male 0.525253 0.122334 0.647587
All 0.616162 0.383838 1.000000

 

추가로, margins를 True로 하면 각 행, 열의 합계를 보여줍니다.