-
혼자 공부하는 데이터 분석 CH 04 통계와 분포Study/Data Analysis 2025. 9. 24. 11:27

목차
- 들어가며
- 통계로 요약하기
- 데이터 로드 및 기본 확인
- 기술통계 구하기
- 평균 (Mean)
- 중앙값 (Median)
- 최솟값과 최댓값
- 분위수 (Quantile)
- 분산 (Variance)
- 표준편차 (Standard Deviation)
- 최빈값 (Mode)
- 데이터프레임 전체 통계
- NumPy 통계 함수들
- 실전 문제 해결
- 핵심 개념 정리
- 분포 요약하기
- 데이터 로드 및 준비
- 산점도 그리기
- 히스토그램 그리기
- 상자 수염 그림 (Box Plot)
- 판다스의 그래프 함수들
- 실전 문제 해결
- 핵심 개념 정리
- 마치며
들어가며
데이터 분석의 첫걸음은 주어진 데이터를 제대로 이해하는 것에서 시작합니다.
방대한 양의 데이터를 한눈에 파악하기란 쉽지 않지만, 통계적인 방법을 사용하면 데이터의 중심 경향성, 퍼진 정도 등 핵심적인 특징을 몇 개의 숫자로 요약할 수 있습니다. 또한, 시각화는 이러한 숫자들을 더욱 직관적으로 이해할 수 있게 돕는 강력한 도구입니다.
이 글에서는 파이썬의 Pandas, NumPy, Matplotlib 라이브러리를 활용하여 데이터를 통계량으로 요약하고, 산점도, 히스토그램, 상자 수염 그림 등 다양한 그래프로 데이터의 분포를 시각화하는 방법을 체계적으로 정리해보겠습니다.
4-1 통계로 요약하기
데이터 로드 및 기본 확인
먼저 분석에 사용할 데이터를 불러오고 head()를 상횽해 기본적인 구조를 확인합니다.
import gdown gdown.download('<https://bit.ly/3736JW1>', 'ns_book6.csv', quiet=False) import pandas as pd ns_book6 = pd.read_csv('ns_book6.csv', low_memory=False) ns_book6.head()기술통계 구하기
describe() 메서드로 전체 요약
describe() 메서드는 수치형 컬럼의 개수, 평균, 표준편차, 최솟값, 사분위수, 최댓값 등 주요 통계량을 한 번에 보여줍니다.
ns_book6.describe()데이터 필터링
분석에 불필요하거나 의미 없는 데이터를 제거합니다. 예를 들어 '도서권수'가 0인 데이터를 제외합니다.
# 도서권수가 0인 행 확인 및 제거 sum(ns_book6['도서권수']==0) ns_book7 = ns_book6[ns_book6['도서권수']>0] # 사용자 정의 분위수로 요약 ns_book7.describe(percentiles=[0.3, 0.6, 0.9]) # 문자열 컬럼 요약 ns_book7.describe(include='object')평균 (Mean)
데이터의 합을 데이터의 개수로 나눈 값으로, 데이터의 중심을 나타내는 대표적인 값입니다.
# 직접 계산 x = [10, 20, 30] sum = 0 for i in range(3): sum += x[i] print("평균:", sum / len(x)) # pandas 내장 함수 ns_book7['대출건수'].mean()중앙값 (Median)
데이터를 크기순으로 나열했을 때 중앙에 위치하는 값입니다. 극단적인 값(이상치)의 영향을 덜 받는 특징이 있습니다.
ns_book7['대출건수'].median() # 간단한 예제로 확인 temp_df = pd.DataFrame([1,2,3,4]) temp_df.median() # 결과: 2.5 (2와 3의 평균) # 중복값 제거 후 중앙값 ns_book7['대출건수'].drop_duplicates().median()최솟값과 최댓값
데이터에서 가장 작은 값과 가장 큰 값을 의미합니다.
ns_book7['대출건수'].min() ns_book7['대출건수'].max()분위수 (Quantile)
데이터를 크기순으로 정렬한 뒤, 특정 비율에 해당하는 위치의 값을 의미합니다.
1사분위수(Q1)는 25%, 2사분위수(Q2)는 50%(중앙값), 3사분위수(Q3)는 75% 지점의 값입니다.
ns_book7['대출건수'].quantile(0.25) ns_book7['대출건수'].quantile([0.25,0.5,0.75])분위수 보간법
- 데이터 개수로 정확히 나누어떨어지지 않을 때, 주변 값을 이용해 계산하는 방법입니다.
# 기본 보간법 (linear) pd.Series([1,2,3,4,5]).quantile(0.9) # 결과: 4.6 # 다른 보간법들 pd.Series([1,2,3,4,5]).quantile(0.9, interpolation='midpoint') pd.Series([1,2,3,4,5]).quantile(0.9, interpolation='nearest')분위수 활용 - 비율 계산
# 대출건수가 10 미만인 비율 borrow_10_flag = ns_book7['대출건수'] < 10 borrow_10_flag.mean() # 65분위수 확인 ns_book7['대출건수'].quantile(0.65)분산 (Variance)
데이터가 평균으로부터 얼마나 퍼져 있는지를 나타내는 지표입니다. 편차(각 값 - 평균)의 제곱의 평균으로 계산됩니다.
# 표본분산 (기본값: ddof=1) ns_book7['대출건수'].var()표준편차 (Standard Deviation)
분산에 제곱근을 취한 값으로, 분산과 동일하게 데이터의 퍼진 정도를 나타냅니다. 원래 데이터와 단위가 같아 해석이 용이합니다.
# 표본표준편차 ns_book7['대출건수'].std() # 직접 계산으로 확인 import numpy as np diff = ns_book7['대출건수'] - ns_book7['대출건수'].mean() np.sqrt(np.sum(diff**2) / (len(ns_book7)-1))최빈값 (Mode)
데이터에서 가장 빈번하게 나타나는 값입니다.
ns_book7['도서명'].mode() ns_book7['발행년도'].mode()데이터프레임 전체 통계
데이터프레임 전체에 대해 통계 함수를 적용할 수 있습니다.
# 수치형 컬럼들의 평균 ns_book7.mean(numeric_only=True) # 모든 컬럼의 최빈값 (문자열 포함) ns_book7.loc[:, '도서명':].mode() # 최종 데이터 저장 ns_book7.to_csv('ns_book7.csv', index=False)NumPy 통계 함수들
NumPy 라이브러리는 더 빠르고 다양한 통계 함수를 제공합니다.
- 평균과 가중평균
- 가중평균은 각 데이터 값의 중요도가 다를 때 사용합니다.
import numpy as np # 일반 평균 np.mean(ns_book7['대출건수']) # 가중평균 (도서권수로 가중치 적용) np.average(ns_book7['대출건수'], weights=1/ns_book7['도서권수']) ns_book7['대출건수'].sum()/ns_book7['도서권수'].sum()- 기타 통계량
np.median(ns_book7['대출건수']) np.min(ns_book7['대출건수']) np.max(ns_book7['대출건수']) np.quantile(ns_book7['대출건수'], [0.25,0.5,0.75])- 분산과 표준편차 - ddof 매개변수
- ddof는 자유도를 의미하며, 분모를 n-ddof로 설정합니다. ddof=0은 모분산, ddof=1은 표본분산을 계산합니다.
# 모분산 (ddof=0) np.var(ns_book7['대출건수']) # 표본분산 (ddof=1) np.var(ns_book7['대출건수'], ddof=1) # 표준편차 np.std(ns_book7['대출건수'])- NumPy로 최빈값 구하기
values, counts = np.unique(ns_book7['도서명'], return_counts=True) max_idx = np.argmax(counts) values[max_idx]실전 문제 해결
- 출판사별 평균 대출건수 상위 10개
- groupby()를 사용하여 특정 그룹별 통계를 쉽게 계산할 수 있습니다.
ns_book7[['출판사','대출건수']].groupby('출판사').mean().sort_values('대출건수', ascending=False).head(10)- IQR(사분위수 범위) 내 데이터 비율
- IQR(Inter-Quartile Range)은 Q3와 Q1의 차이로, 데이터의 중간 50%가 포함된 범위입니다.
# 1사분위수와 3사분위수 구하기 target_range = np.array(ns_book7['대출건수'].quantile(q=[0.25,0.75])) # IQR 범위 내 데이터 필터링 target_bool_idx = (ns_book7['대출건수'] >= target_range[0]) & (ns_book7['대출건수'] <= target_range[1]) # 전체 데이터 중 비율 계산 target_bool_idx.sum()/len(ns_book7)*100핵심 개념 정리
- 기술통계: 데이터의 주요 특성을 숫자로 요약하는 방법.
- describe(): 수치형 데이터의 주요 통계량을 한 번에 확인하는 메서드.
- 중심경향성 측도: 평균, 중앙값, 최빈값으로 데이터의 중심을 나타냄.
- 산포 측도: 분산, 표준편차, 분위수로 데이터의 퍼진 정도를 나타냄.
- ddof 매개변수: 분산 계산 시 분모를 조정 (0: 모분산, 1: 표본분산).
- IQR: Q3-Q1으로 중간 50% 데이터의 범위.
- groupby(): 범주별로 그룹화하여 통계량 계산 시 사용.
4-2 분포 요약하기
데이터 로드 및 준비
앞서 저장한 데이터를 다시 불러와 시각화 분석을 준비합니다.
import gdown gdown.download('<https://bit.ly/3pK7iuu>', 'ns_book7.csv', quiet=False) import pandas as pd ns_book7 = pd.read_csv('ns_book7.csv', low_memory=False) ns_book7.head()
산점도 그리기
산점도는 두 변수 간의 관계를 점으로 표현한 그래프입니다.
- 기본 산점도
import matplotlib.pyplot as plt # 도서권수와 대출건수 관계 plt.scatter(ns_book7['도서권수'], ns_book7['대출건수']) plt.show()- 투명도 조정으로 겹침 해결
- 데이터 포인트가 많아 겹쳐 보일 때 alpha 매개변수로 투명도를 조절하면 밀도를 파악하기 용이합니다.
plt.scatter(ns_book7['도서권수'], ns_book7['대출건수'], alpha=0.1) plt.show()- 새로운 변수 생성하여 분석
- 기존 변수를 조합하여 새로운 변수를 만들고 관계를 파악할 수 있습니다.
# 도서 1권당 평균 대출건수 계산 average_borrows = ns_book7['대출건수']/ns_book7['도서권수'] plt.scatter(average_borrows, ns_book7['대출건수'], alpha=0.1) plt.show()
히스토그램 그리기
히스토그램은 특정 구간에 해당하는 데이터의 개수(빈도)를 막대그래프로 나타내어 데이터의 전체적인 분포를 확인할 수 있습니다.
- 기본 히스토그램
plt.hist([0,3,5,6,7,7,9,13], bins=5) # bins: 구간 개수 plt.show()- 실제 데이터 히스토그램과 스케일 조정
- 데이터가 특정 구간에 몰려있어 분포를 확인하기 어려울 때, 로그 스케일을 적용하면 유용합니다.
# 대출건수 히스토그램 plt.hist(ns_book7['대출건수']) plt.yscale('log') # y축을 로그 스케일로 plt.show() # 구간 수를 늘려 더 자세히 확인 plt.hist(ns_book7['대출건수'], bins=100) plt.yscale('log') plt.show()- 문자열 길이 분포 분석
- apply() 함수를 사용해 각 도서명의 길이를 계산하고 분포를 확인할 수 있습니다.
title_len = ns_book7['도서명'].apply(len) plt.hist(title_len, bins=100) plt.show()
상자 수염 그림 (Box Plot)
데이터의 사분위수, 중앙값, 이상치 등을 한 번에 보여주어 분포를 요약적으로 파악하는 데 효과적인 그래프입니다.
- 기본 상자 수염 그림
plt.boxplot(ns_book7[['대출건수','도서권수']]) plt.yscale('log') plt.show()- 상자 수염 그림 옵션들
- vert=False로 수평으로 그리거나, whis 매개변수로 이상치를 판단하는 범위를 조절할 수 있습니다.
# 수평 방향으로 그리기 plt.boxplot(ns_book7[['대출건수','도서권수']], vert=False) plt.xscale('log') plt.show() # 이상치 범위 조정 (기본값은 1.5) plt.boxplot(ns_book7[['대출건수','도서권수']], whis=10) plt.yscale('log') plt.show()판다스의 그래프 함수들
Pandas는 Matplotlib을 기반으로 한 자체적인 시각화 함수를 제공하여 더 간편하게 그래프를 그릴 수 있습니다.
- 판다스 산점도
ns_book7.plot.scatter('도서권수', '대출건수', alpha=0.1) plt.show()- 판다스 히스토그램
ns_book7['도서명'].apply(len).plot.hist(bins=100) plt.show()- 판다스 상자 수염 그림
ns_book7[['대출건수','도서권수']].boxplot() plt.yscale('log') plt.show()실전 문제 해결
- 특정 기간 데이터 필터링 및 시각화
- 조건에 맞는 데이터만 선택하여 분포를 시각화할 수 있습니다.
# 1980년~2022년 사이 발행된 도서들만 선택 selected_rows = (1980 <= ns_book7['발행년도']) & (ns_book7['발행년도'] <= 2022) # 발행년도 히스토그램 plt.hist(ns_book7.loc[selected_rows, '발행년도']) plt.show() # 발행년도 상자 수염 그림 plt.boxplot(ns_book7.loc[selected_rows, '발행년도']) plt.show()핵심 개념 정리
- 산점도: 두 연속형 변수 간의 관계를 시각화하는 그래프. alpha 매개변수로 투명도 조절 가능.
- 히스토그램: 연속형 변수의 분포를 시각화하는 그래프. bins로 구간 개수 조절, log=True로 로그 스케일 적용 가능.
- 로그 스케일: 극단값이 있거나 범위가 넓은 데이터를 시각화할 때 유용.
- 상자 수염 그림: 데이터의 분포와 이상치를 한눈에 파악. 중앙값, 사분위수, 이상치를 동시에 표시.
- 판다스 플롯 기능: Matplotlib 기반의 간편한 시각화 메서드.
- 데이터 필터링: 불린 인덱싱으로 조건에 맞는 데이터만 선택하여 시각화.
마치며
지금까지 데이터를 숫자로 요약하는 기술통계 방법과 분포를 한눈에 파악하는 시각화 기법에 대해 알아보았습니다.
평균, 중앙값, 분산 등의 통계량은 데이터의 특징을 압축적으로 설명해주며,
산점도, 히스토그램, 상자 수염 그림은 이러한 특징을 직관적으로 이해하도록 돕습니다.
데이터를 제대로 이해하는 것은 정확한 분석과 올바른 의사결정의 기반이 됩니다.
여기에 정리된 내용들을 바탕으로 다양한 데이터를 탐색하고 분석하는 능력을 키워나가시길 바랍니다.
코드 출처:
https://colab.research.google.com/github/rickiepark/hg-da/blob/main/04-1.ipynb
04-1.ipynb
Run, share, and edit Python notebooks
colab.research.google.com
https://colab.research.google.com/github/rickiepark/hg-da/blob/main/04-2.ipynb
04-2.ipynb
Run, share, and edit Python notebooks
colab.research.google.com
https://www.youtube.com/watch?v=HNlRYQnLkek&list=PLVsNizTWUw7FGzSRCkQrPEEe-ljVXgS7k&index=8
https://www.youtube.com/watch?v=Cbk_tQtuhbM&list=PLVsNizTWUw7FGzSRCkQrPEEe-ljVXgS7k&index=9
'Study > Data Analysis' 카테고리의 다른 글
혼자 공부하는 데이터 분석 CH 06 복잡한 데이터 표현하기 (0) 2025.09.26 혼자 공부하는 데이터 분석 CH 05 데이터 시각화 (3) 2025.09.25 혼자 공부하는 데이터 분석 CH 03 데이터 클렌징 (1) 2025.09.23 혼자 공부하는 데이터 분석 CH 02 웹 스크래핑 (0) 2025.09.22 혼자 공부하는 데이터 분석 CH 01 데이터 분석 (0) 2025.09.21