Skip to main content

집계와 통계

NumPy는 배열의 데이터를 요약하는 다양한 집계(Aggregation) 함수를 제공합니다. 축(axis) 개념을 이해하면 행 방향, 열 방향, 또는 전체에 대해 유연하게 통계량을 계산할 수 있습니다.

학습 목표

  • 축(axis) 개념을 이해하고 원하는 방향으로 집계할 수 있다
  • 기술통계 함수(mean, std, median 등)를 활용할 수 있다
  • 누적 연산(cumsum, cumprod)을 수행할 수 있다
  • 결측치(NaN)를 안전하게 처리하는 집계 함수를 사용할 수 있다

왜 중요한가

데이터 분석의 첫 단계는 데이터의 분포와 경향을 파악하는 것입니다. 피처별 평균, 표준편차, 최솟값, 최댓값을 계산하면 데이터의 스케일과 분포 특성을 빠르게 이해할 수 있습니다. 이 정보는 전처리 전략(스케일링, 정규화)과 이상치 탐지의 기초가 됩니다.

축(axis) 이해

import numpy as np

arr = np.array([[1, 2, 3],
                [4, 5, 6]])  # shape: (2, 3)

# axis=None: 전체 원소 대상 (기본값)
print(np.sum(arr))           # 21

# axis=0: 행 방향(위→아래)으로 집계 → 결과 shape: (3,)
print(np.sum(arr, axis=0))   # [5 7 9]

# axis=1: 열 방향(왼→오른)으로 집계 → 결과 shape: (2,)
print(np.sum(arr, axis=1))   # [ 6 15]
axis 값집계 방향제거되는 차원2D 배열 결과
None전체모든 차원스칼라
0행 방향 (위→아래)행 차원1D (열 수만큼)
1열 방향 (왼→오른)열 차원1D (행 수만큼)
axis=0은 “0번 축을 따라 접는다(collapse)“로 이해하면 직관적입니다. 0번 축(행)을 접으면 열만 남습니다.

기본 집계 함수

data = np.array([[10, 20, 30],
                 [40, 50, 60],
                 [70, 80, 90]])

# 합계
print(np.sum(data, axis=0))    # [120 150 180] — 열별 합계

# 평균
print(np.mean(data, axis=1))   # [20. 50. 80.] — 행별 평균

# 최솟값, 최댓값
print(np.min(data))            # 10 — 전체 최솟값
print(np.max(data, axis=0))    # [70 80 90] — 열별 최댓값

# 최솟값/최댓값의 인덱스
print(np.argmin(data, axis=1)) # [0 0 0] — 각 행에서 최솟값의 열 인덱스
print(np.argmax(data, axis=0)) # [2 2 2] — 각 열에서 최댓값의 행 인덱스

기술통계 함수

scores = np.array([85, 92, 67, 78, 95, 73, 88, 91, 62, 80])

# 중심 경향
print(f"평균: {np.mean(scores):.1f}")        # 81.1
print(f"중앙값: {np.median(scores):.1f}")     # 82.5

# 산포도
print(f"분산: {np.var(scores):.1f}")          # 110.5
print(f"표준편차: {np.std(scores):.1f}")       # 10.5
print(f"범위: {np.ptp(scores)}")              # 33 (최댓값 - 최솟값)

# 백분위수
print(f"25th: {np.percentile(scores, 25):.1f}")   # 73.8
print(f"75th: {np.percentile(scores, 75):.1f}")   # 90.3
print(f"IQR: {np.percentile(scores, 75) - np.percentile(scores, 25):.1f}")  # 16.5
함수설명용도
np.mean()산술 평균중심 경향
np.median()중앙값이상치에 강건한 중심값
np.var()분산산포도 측정
np.std()표준편차산포도 (평균과 동일 단위)
np.percentile()백분위수분포 위치 파악
np.ptp()범위(max-min)데이터 폭

누적 연산

arr = np.array([1, 2, 3, 4, 5])

# 누적 합
print(np.cumsum(arr))    # [ 1  3  6 10 15]

# 누적 곱
print(np.cumprod(arr))   # [  1   2   6  24 120]

# 2D 배열의 축별 누적합
matrix = np.array([[1, 2, 3],
                   [4, 5, 6]])
print(np.cumsum(matrix, axis=1))
# [[ 1  3  6]
#  [ 4  9 15]]

NaN 안전 함수

실제 데이터에는 결측치(NaN)가 포함된 경우가 많습니다. 일반 집계 함수는 NaN이 하나라도 있으면 결과가 NaN이 됩니다.
data = np.array([1.0, 2.0, np.nan, 4.0, 5.0])

# 일반 함수 — NaN 전파
print(np.mean(data))       # nan
print(np.sum(data))        # nan

# NaN 안전 함수 — NaN 무시
print(np.nanmean(data))    # 3.0
print(np.nansum(data))     # 12.0
print(np.nanstd(data))     # 1.414...
print(np.nanmin(data))     # 1.0
print(np.nanmax(data))     # 5.0
일반 함수NaN 안전 함수동작
np.mean()np.nanmean()NaN 제외 후 평균
np.sum()np.nansum()NaN 제외 후 합계
np.std()np.nanstd()NaN 제외 후 표준편차
np.min()np.nanmin()NaN 제외 후 최솟값
np.max()np.nanmax()NaN 제외 후 최댓값

AI/ML에서의 활용

  • 피처 스케일링: 각 피처의 mean(axis=0)std(axis=0)을 구해 Z-score 정규화를 수행합니다
  • 모델 평가: 교차 검증 결과의 평균과 표준편차로 모델 성능을 요약합니다
  • 배치 통계: 배치 정규화에서 axis=0 집계로 배치 내 통계를 계산합니다
  • 이상치 탐지: IQR(사분위 범위)을 계산하여 이상치 경계를 설정합니다
ddof(Delta Degrees of Freedom)는 자유도 보정값입니다. ddof=0(기본값)은 모표준편차, ddof=1은 표본표준편차를 계산합니다. Pandas의 .std()ddof=1이 기본값이므로, NumPy와 Pandas의 표준편차 결과가 다를 수 있습니다.
keepdims=True를 설정하면 집계 후에도 차원 수가 유지됩니다. 브로드캐스팅과 함께 사용할 때 유용합니다. 예: mean = arr.mean(axis=0, keepdims=True)로 하면 원본 배열에서 바로 빼기 연산이 가능합니다.

체크리스트

  • axis=0, axis=1, axis=None의 차이를 설명할 수 있다
  • mean, median, std, percentile을 활용하여 데이터를 요약할 수 있다
  • argmin, argmax로 최솟값/최댓값의 위치를 찾을 수 있다
  • NaN이 포함된 데이터에서 nanmean, nanstd 등을 적절히 사용할 수 있다
  • keepdims를 활용하여 브로드캐스팅 호환성을 유지할 수 있다

다음 문서