#시작에 앞서 간단한 tip
〔전처리 예시: 결측치 처리〕
결측치는 데이터에서 값이 비어있는 경우를 말합니다. 결측치가 있으면 분석 결과가 왜곡되거나, 모델 학습이 제대로 되지 않을 수 있어요. 또한 결측치 처리 방법도 상황에 따라 선택이 달라집니다.
• 삭제: 결측치 비율이 낮고, 데이터가 충분할 때
• 평균/중앙값 대체: 수치형 데이터이고, 분포 특성에 맞게 선택
• 최빈값 대체: 범주형 데이터일 때
• 보간법: 시계열 데이터처럼 순서가 있는 경우
• 별도 범주 처리: 결측 자체가 의미 있는 정보일 때
"어떤 메서드를 쓰는가"보다 "왜 이 방법을 선택했는가? 현재 나의 분석에서 어떤 방법이 적절한가?" 설명할 수 있어야 합니다.
df2 = df2.rename(columns={"qty": "quantity"})
df2에서 "qty"라는 컬럼 이름을 "quantity"라는 이름으로 바꿈
qty → quantity 라는 사전(dictionary)을 준 것.
예를 들어 이런 컬럼이 있다고 해보자
temp_price
debug_flag
memo
이 상태에서 df.mean()을 하면 의미 없는 컬럼까지 평균에 포함될 수 있다.
& 분석은 항상 질문에 답하기 위한 건데, '매출 분석하기'라고 해놓고
매출과 무관한 컬럼이 잔뜩 있으면 분석의 초점이 흐려진다.
👉 원본 데이터를 파괴하지 않으면서 df2라는 분석용 테이블에서만 특정 칼럼을 제외할 때 drop() 사용
df2 = df2.drop(columns=["memo", "temp_col"])
같은 의미의 값들을 컴퓨터가 같은 대상으로 인식하게 만드는 과정
(대소문자나 공백 등으로 인해 의미는 같으나 다르게 쓰인 경우 다른 대상으로 인식)
df2["menu"] = (
df2["menu"]
.astype(str)
.str.strip()
.str.title()
)
df2["menu"].value_counts()
(1) .astype(str)로 menu 컬럼 내 값들을 문자열로 통일
(2) .str.strip()로 앞뒤 공백 제거(오류 방지)
(3) .tr.title() : 첫 글자 대문자, 나머지 소문자 로 통일
※ 참고: .lower() : 소문자로 통일 / .upper() : 대문자로 통일
(4) df2["menu"].value_counts()로 정리가 잘 되었는지 확인
e.g. menu에 "ice americano", "Ice Americano" 같은 값이 있다면 정리 안 된 것
실무 데이터에서 price는 보통 이렇게 들어온다.
"10,000원"
"5000원"
" 3,200 "
"무료"
None
이런 형태들로는 분석 자체가 불가능하므로 정리가 필요하다.
문자열로 정리(불필요한 내용 제거) → 숫자로 변환
df2["price"] = (
df2["price"]
.astype(str)
.str.replace(",", "", regex=False)
.str.replace("원", "", regex=False)
.str.strip()
)
쉼표 ❌, 통화 단위 ❌, 공백 ❌
regex = Fale : ",", "원"처럼 딱 정해진 글자만 지우고 싶을 때.str.replace("[", "")
이건 정규표현식 문법이라 에러가 나거나 이상하게 작동한다.
이런 경우를 막기 위해 그냥 '글자 그 자체'로 읽어들이라는 regex = Fale 입력.
df2["price"] = pd.to_numeric(df2["price"], errors="coerce")
숫자로 바꿀 수 있으면 바꾸고, 못 바꾸면 NaN으로 처리
errors="coerce"가 없으면 에러 때문에 프로그램이 작동하지 않음df2["price"].isnull().sum()
숫자로 안 바뀐(비어있는) price가 몇 개인지 파악
is.null() : 값이 비어있으면 True, 값이 있으면 False.sum() : True를 1로 세어 몇 개인지 계산.dropna() : 값이 없는 행을 분석에서 제외.fillna() : 값이 없으면 다른 값으로 대체✔ dropna를 써야 하는 상황
👉 price가 없으면 매출 계산이 안 된다.
👉 quantity가 없으면 판매량 계산이 안 된다.
clean = df2.dropna(subset=["price", "quantity"]).copy()
✔ fill이 가능한 상황
e.g. 리뷰 수, 할인 금액, 쿠폰 사용 횟수
.copy() : df2의 복제품 clean을 만들어 clean을 마음껏 수정해도 df2에 영향 없음.shape : (행의 개수, 열의 개수) 도출. 결측치 처리 후 데이터가 얼마나 많이 줄었는지 확인할 수 있음
- 컬럼명 정리 (rename / drop)
- 문자열 정리 (menu, paid 등)
- 숫자 정리 (price, quantity)
- 결측치 처리 (dropna / fillna)
regex=False, errors="coerce" 같은 옵션들의 역할을 제대로 이해하기 전에는 필요성을 느끼지 못했다.
'이걸 안 쓰면 어떻게 되지?', '지금은 잘 되는데, 왜 굳이 쓰는 거지?' 등의 질문을 통해 옵션은 실수를 막기 위한 장치라는 걸 이해했다. 특히 regex=False를 사용해 지금은 차이가 없어 보이지만, 나중에 큰 문제를 만들 수 있는 지점을 미리 차단하는 방식은 실무적인 사고방식에 가깝다는 생각이 들었다.
결측치 처리를 할 때는 단순히 결측치를 채우거나 버리는 행위에 집중하기보다, '이 값이 없으면 지금 이 분석이 성립하는가?'를 늘 생각해야 한다. 분석 의도에 적합하게 결측치 처리를 하는 것이 중요하다.