Python 실전 데이터 분석 | Pandas로 데이터 분석하기
이 글의 핵심
Python 실전 데이터 분석에 대해 정리한 개발 블로그 글입니다. import pandas as pd import numpy as np
들어가며
”데이터에서 인사이트 찾기”
실전 데이터 분석은 데이터를 이해하고 의미를 찾는 과정입니다.
1. 데이터 로드와 탐색
기본 탐색
CSV를 read_csv로 불러오면 큰 표 하나가 메모리에 올라온 상태입니다. shape로 행·열 개수를 보고, info·describe로 타입과 수치 분포를 훑은 뒤, head로 실제 값 몇 줄을 눈으로 확인합니다.
import pandas as pd
import numpy as np
# 데이터 로드
df = pd.read_csv('sales_data.csv')
# 기본 정보
print(f"데이터 크기: {df.shape}")
print(f"\n열 정보:")
print(df.info())
print(f"\n통계 요약:")
print(df.describe())
print(f"\n처음 5행:")
print(df.head())
# 결측치 확인
print(f"\n결측치:")
print(df.isnull().sum())
2. 탐색적 데이터 분석 (EDA)
분포 확인
import matplotlib.pyplot as plt
# 히스토그램
df['age'].hist(bins=20)
plt.title('나이 분포')
plt.xlabel('나이')
plt.ylabel('빈도')
plt.show()
# 박스플롯 (이상치 확인)
df.boxplot(column='salary', by='department')
plt.title('부서별 연봉 분포')
plt.show()
상관관계 분석
import seaborn as sns
# 상관계수 계산
corr_matrix = df[['age', 'salary', 'experience']].corr()
print(corr_matrix)
# 히트맵
sns.heatmap(corr_matrix, annot=True, cmap='coolwarm')
plt.title('상관관계 히트맵')
plt.show()
3. 그룹 분석
집계 분석
# 부서별 평균 연봉
dept_avg = df.groupby('department')['salary'].mean()
print(dept_avg)
# 여러 집계
result = df.groupby('department').agg({
'salary': ['mean', 'min', 'max'],
'age': 'mean',
'name': 'count'
})
print(result)
# 피벗 테이블
pivot = df.pivot_table(
values='salary',
index='department',
columns='gender',
aggfunc='mean'
)
print(pivot)
4. 시계열 분석
시계열 데이터
# 날짜 파싱
df['date'] = pd.to_datetime(df['date'])
df = df.set_index('date')
# 리샘플링 (일 → 월)
monthly = df.resample('M').sum()
# 이동 평균
df['ma7'] = df['sales'].rolling(window=7).mean()
df['ma30'] = df['sales'].rolling(window=30).mean()
# 시각화
plt.figure(figsize=(12, 6))
plt.plot(df.index, df['sales'], label='일별 매출', alpha=0.5)
plt.plot(df.index, df['ma7'], label='7일 이동평균')
plt.plot(df.index, df['ma30'], label='30일 이동평균')
plt.legend()
plt.title('매출 추이')
plt.show()
5. 실전 예제
고객 분석
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
# 데이터 로드
customers = pd.read_csv('customers.csv')
# 1. 기본 통계
print("=== 기본 통계 ===")
print(f"총 고객 수: {len(customers)}")
print(f"평균 나이: {customers['age'].mean():.1f}세")
print(f"평균 구매액: {customers['purchase_amount'].mean():,.0f}원")
# 2. 연령대별 분석
customers['age_group'] = pd.cut(
customers['age'],
bins=[0, 20, 30, 40, 50, 100],
labels=['10대', '20대', '30대', '40대', '50대+']
)
age_analysis = customers.groupby('age_group').agg({
'purchase_amount': ['mean', 'sum', 'count']
})
print("\n=== 연령대별 분석 ===")
print(age_analysis)
# 3. 시각화
fig, axes = plt.subplots(2, 2, figsize=(12, 10))
# 연령 분포
axes[0, 0].hist(customers['age'], bins=20, edgecolor='black')
axes[0, 0].set_title('연령 분포')
# 구매액 분포
axes[0, 1].hist(customers['purchase_amount'], bins=30, edgecolor='black')
axes[0, 1].set_title('구매액 분포')
# 연령대별 평균 구매액
age_group_avg = customers.groupby('age_group')['purchase_amount'].mean()
axes[1, 0].bar(age_group_avg.index, age_group_avg.values)
axes[1, 0].set_title('연령대별 평균 구매액')
axes[1, 0].tick_params(axis='x', rotation=45)
# 상관관계
numeric_cols = customers[['age', 'purchase_amount', 'visit_count']]
sns.heatmap(numeric_cols.corr(), annot=True, ax=axes[1, 1])
axes[1, 1].set_title('상관관계')
plt.tight_layout()
plt.savefig('customer_analysis.png', dpi=300)
plt.show()
# 4. 인사이트 도출
print("\n=== 인사이트 ===")
print(f"가장 많이 구매하는 연령대: {age_group_avg.idxmax()}")
print(f"평균 구매액이 가장 높은 연령대: {age_group_avg.idxmax()}")
데이터 이해 → 가설 → 검증 → 인사이트
탐색적 데이터 분석(EDA)은 질문을 세우고, 표와 그래프로 답을 찾는 과정입니다. 열 의미·타입·결측을 본 뒤 가설을 정하고, 시각화와 통계로 검증한 다음, 비즈니스에 쓸 수 있는 문장으로 정리합니다.
# 1. 데이터 이해
# - 각 열의 의미
# - 데이터 타입
# - 결측치/이상치
# 2. 가설 수립
# - "연령이 높을수록 구매액이 높을까?"
# - "주말에 매출이 높을까?"
# 3. 검증
# - 시각화
# - 통계 분석
# - 상관관계
# 4. 인사이트 도출
# - 비즈니스 의미
# - 액션 아이템
실전 심화 보강
실전 예제: 이상치 플래그 + 요약 테이블 (pandas)
아래는 수치 열에 대해 IQR 기준 이상치 행을 표시하고, 그룹별 요약을 뽑는 실행 가능한 스크립트입니다.
import numpy as np
import pandas as pd
rng = np.random.default_rng(7)
df = pd.DataFrame({
"region": rng.choice(["A", "B", "C"], size=400),
"revenue": rng.normal(100, 25, size=400),
})
def iqr_bounds(s: pd.Series, k: float = 1.5):
q1, q3 = s.quantile([0.25, 0.75])
iqr = q3 - q1
lo, hi = q1 - k * iqr, q3 + k * iqr
return lo, hi
lo, hi = iqr_bounds(df["revenue"])
df["outlier"] = (df["revenue"] < lo) | (df["revenue"] > hi)
summary = df.groupby("region")["revenue"].agg(["count", "mean", "std", "median"])
print(summary)
print("이상치 비율:", df["outlier"].mean())
자주 하는 실수
- 결측치를 제거하지 않은 채 평균·상관을 계산하는 경우.
- 시계열을 정렬하지 않고
rolling·diff를 적용하는 경우. - 시각화만 보고 통계적 유의성 없이 인과를 단정하는 경우.
주의사항
- IQR 규칙은 분포 가정이 약하지만 비즈니스 규칙과 함께 써야 합니다.
- 다중 검정 시 p-value 보정이 필요할 수 있습니다.
실무에서는 이렇게
- 노트북은 재현 가능한 시드와 데이터 스냅샷 버전을 명시합니다.
- 결과는 지표 정의(분자/분모)와 함께 문서화합니다.
비교 및 대안
| 도구 | 역할 |
|---|---|
| pandas | 테이블 변환·집계 |
| SQL | 대용량 집계를 DB에 가깝게 |
| Spark | 분산 배치 |
추가 리소스
정리
핵심 요약
- EDA: 데이터 탐색과 시각화
- 그룹 분석: groupby, pivot_table
- 시계열: resample, rolling
- 시각화: Matplotlib, Seaborn
- 인사이트: 데이터 → 의사결정
다음 단계
- 파일 자동화
- 웹 스크래핑
관련 글
- Pandas 기초 | Python 데이터 분석 라이브러리 완벽 정리