파이썬 교재 · 21편 / 27편

파이썬 pandas 기초 — DataFrame·groupby

엑셀로 하루 잡일이 코드 5줄로. 데이터 분석의 시작.

중급읽는 시간 7분2026-05-13
pandas read_csv 와 groupby 로 매출 평균을 구하는 코드 화면

엑셀에서 매출 5만 행을 열어 SUMIF 와 피벗 테이블로 한 시간 작업하는 것 — pandas 가 깔리면 5-10줄짜리 파이썬 코드로 끝납니다. 데이터 과학자만의 도구가 아니에요. 회사에서 CSV·엑셀을 자주 만지는 누구든 한 달이면 본전을 뽑습니다.

21편을 마치면 ① DataFrame 의 본질 ② read_csv 와 첫 탐색 ③ 필터·정렬·새 컬럼 ④ groupby 집계 ⑤ 결측값(NaN) 처리 — 5가지가 손에 익습니다.

DataFrame — 표 모양의 자료구조

(.venv) $ pip install pandas

import pandas as pd

# dict 로 만들기 — list of dict 의 진화형
data = {
    "name": ["준성", "수민", "지훈"],
    "age": [30, 28, 35],
    "score": [88, 92, 75],
}
df = pd.DataFrame(data)
#    name  age  score
# 0  준성   30     88
# 1  수민   28     92
# 2  지훈   35     75

df.shape          # (3, 3) — 행, 열
df.columns        # Index(['name', 'age', 'score'])
df.dtypes         # 컬럼별 자료형

DataFrame 은 컬럼이 키, 행이 값인 똑똑한 dict입니다. 각 컬럼이 Series(똑똑한 list)이고, 그 묶음이 DataFrame. 5편의 list + 6편의 dict 가 합쳐져 진화한 형태로 이해하면 자연스러워요.

CSV 읽기와 첫 탐색

df = pd.read_csv("sales.csv")

df.head()         # 처음 5행
df.tail(3)        # 마지막 3행
df.info()         # 컬럼·자료형·결측 수 한눈에
df.describe()     # 숫자 컬럼의 평균·표준편차·min·max·분위수
df["item"].value_counts()   # 카테고리 컬럼의 빈도

# 엑셀도 한 줄로
df = pd.read_excel("data.xlsx", sheet_name="2026Q2")
df.to_csv("out.csv", index=False, encoding="utf-8-sig")
# index=False 안 적으면 0,1,2,... 인덱스가 컬럼으로 저장됨

describe()info() 는 새 데이터를 받으면 가장 먼저 호출. 행 수·자료형·결측·이상치를 5초에 파악합니다.

📌 CSV 인코딩 함정

한글 엑셀에서 만든 CSV 는 cp949 또는 utf-8-sig(BOM 포함) 인 경우가 많습니다. encoding="utf-8" 로 안 읽히면 encoding="cp949" 또는 encoding="utf-8-sig" 시도. 저장도 to_csv(..., encoding="utf-8-sig") 가 엑셀에서 잘 열려요.

필터·정렬·새 컬럼

# 한 컬럼 선택
df["score"]              # Series — 한 컬럼
df[["name", "score"]]    # DataFrame — 여러 컬럼

# 조건 필터 (boolean indexing)
df[df["score"] >= 80]
df[(df["age"] < 30) & (df["score"] >= 80)]   # & 는 and, | 는 or, ~ 는 not
df.query("score >= 80 and age < 30")          # 같은 결과, SQL 스타일

# 정렬
df.sort_values("score", ascending=False)
df.sort_values(["age", "score"], ascending=[True, False])

# 새 컬럼
df["grade"] = df["score"].apply(
    lambda s: "A" if s >= 90 else "B" if s >= 80 else "C"
)
df["bonus"] = df["score"] * 1.1     # 벡터 연산 — for 안 써도 행마다 적용

df["score"] * 1.1 같은 벡터 연산이 pandas 의 진가입니다. 100만 행이라도 한 줄로 처리되고, 내부적으로 C 로 도는 NumPy 가 수십 배 빠릅니다. 파이썬 for 루프로 매번 처리하면 1000배 차이 나는 경우도.

groupby — 키별 집계

df = pd.read_csv("sales.csv")
# columns: date, item, price, qty

# 상품별 매출 합
df.groupby("item")["price"].sum()
# item
# bread     2400000
# coffee    5400000

# 여러 집계를 동시에
df.groupby("item").agg(
    total_price=("price", "sum"),
    avg_qty=("qty", "mean"),
    rows=("price", "count"),
)

# 다중 키
df.groupby(["date", "item"])["qty"].sum().unstack()
# 날짜×상품 피벗 테이블 — 엑셀 피벗이 한 줄

19편 itertools.groupby 와 비교하면 pandas 가 압도적으로 강력. 정렬 필요 없고, 여러 집계 동시에, 결과가 다시 DataFrame 이라 이어 처리 가능.

결측값 처리 + 마무리

df.isna().sum()              # 컬럼별 결측 수
df.dropna()                  # 결측 있는 행 제거
df.dropna(subset=["price"])  # 특정 컬럼만 기준
df.fillna({"qty": 0, "price": df["price"].mean()})
df["item"] = df["item"].fillna("미분류")
⚠️ 원본을 바꾸지 않는다. df.dropna() 는 새 DataFrame 을 반환하고 df 자체는 그대로. 결과를 df = df.dropna() 로 다시 할당하거나, 옛 옵션 inplace=True(3.0 에서 제거 예정이라 비권장)를 써야 영구 반영. 5편 list 의 sort vs sorted 와 같은 패턴.

다음 미션: ① 매출 CSV(7일×3상품)에서 상품별 총 매출 ② describe() 로 본인 가계부 통계 ③ 결측 있는 컬럼을 평균값으로 채우고 다시 저장.

다음 편 미리보기

22편 — "파이썬 자동화 스크립트": 실전 종합. 지금까지 배운 도구들을 묶어 "매일 9시에 보고서 생성" 같은 일을 한 파일에.

📚 27편 파이썬 교재 시리즈 — 21/27편
← 20편 "requests" · 다음: 22편 "자동화 스크립트"

© 2026 주나이테크(주) @JUNAITECH