[TIL] 멋쟁이사자처럼 그로스 마케팅 부트캠프 수강생 후기 - Pandas 결측치·이상치 처리 정리

Pandas로 결측치(dropna·fillna·중앙값)와 이상치(IQR 방식) 처리하는 방법, loc·iloc 필터링, 파생변수 생성, groupby 집계까지 직접 정리한 멋쟁이사자처럼 그로스 마케팅 4기 수강생의 23일차 TIL 기록이에요.
[TIL] 멋쟁이사자처럼 그로스 마케팅 부트캠프 수강생 후기 - Pandas 결측치·이상치 처리 정리

[멋쟁이사자처럼이 전하는 말]

마케터가 데이터를 다룰 때 가장 먼저 맞닥뜨리는 현실이 있어요. 깔끔하게 정리된 데이터는 교과서 속에만 있고, 실제 데이터에는 빈 칸(결측치)과 튀는 값(이상치)이 가득하다는 것. 이걸 제대로 처리하지 못하면 분석 결과 자체가 틀려버리기 때문에, 데이터 분석의 첫 관문이라고 해도 과언이 아니에요.

멋쟁이사자처럼 부트캠프는 단순히 배우는 것에 그치지 않고, 배운 내용을 내 것으로 만드는 방법까지 함께 고민하고 있어요. 수강생들이 매일 TIL(Today I Learned) 블로그 챌린지로 학습 내용을 기록하는 것도 그 일환이에요.

오늘 소개할 학습 일기 TIL의 주제는 Pandas를 활용한 데이터 결측치·이상치 처리예요. loc·iloc 필터링부터 dropna·fillna·중앙값 채우기, IQR 방식의 이상치 제거, 파생변수 생성, groupby 집계까지 마케터가 실무에서 실제로 쓰는 데이터 처리 흐름을 직접 정리한 멋쟁이사자처럼 그로스 마케팅 부트캠프 4기 수강생의 23일차 기록을 지금 확인해 보세요!

💡

이런 분들이 읽으면 좋아요!

  • 멋쟁이사자처럼 그로스 마케팅 부트캠프가 어떻게 운영되는지 궁금한 분

  • Pandas로 데이터 결측치·이상치 처리하는 방법이 헷갈리는 분

  • 부트캠프 합류 전, 마케터가 데이터 분석을 배우는 과정이 궁금한 분


데이터 결측치, 이상치 처리와 분석

1. Pandas 시작하기

import pandas as pd

 data = {
    'name':         ['Alice', 'Bob', 'Carol', 'Dave', 'Eve',
                    'Frank', 'Grace', 'Hank', 'Ivy', 'Jack'],
    'age':          [25, 30, 28, 35, 22, 41, 33, 27, 45, 31],
    'service':      ['멜론', '스포티파이', '애플뮤직', '멜론', '유튜브뮤직',
                    None, '애플뮤직', '멜론', '스포티파이', '유튜브뮤직'],
    'likes':        [10, 5, None, 8, 3, 12, None, 7, 4, 9],
    'income':       [3200, 4800, None, 5500, 2900, 7200, 4100, None, 6300, 3800],
    'satisfaction': [9, 4, 7, 8, 2, 10, 6, 3, 8, 5],
    'grade':        ['일반', '일반', '일반', '일반', '일반',
                    '일반', '일반', '일반', '일반', '일반']
 }

df = pd.DataFrame(data)
print(df)

➡️ 데이터 더미들은 일단 복사해서 가져온다..! NaN 은 "Not a Number"의 줄임말로, 판다스에서 빈 값을 표현하는 방식으로, None을 넣으면 판다스가 자동으로 NaN으로 바꿈.

  • 데이터 첫 탐색: 데이터를 받으면 무조건 이 세 줄부터 실행

    함수

    하는 일

    df.info()

    컬럼 이름, 타입, 결측치 수를 한번에

    df.describe()

    숫자 컬럼의 평균·최솟값·최댓값 등 기초 통계

    df.head(n)

    처음 n행 미리보기 (기본값 5)

  • 먼저 봐야 하는 이유!마케터가 데이터를 분석할 때 가장 많이 하는 실수가 "데이터를 믿고 바로 계산하는 것"

    ◦ Age 컬럼에 999가 들어있다 → 평균 나이가 말도 안 되게 높게 나옴 ◦ Income 컬럼에 24개가 비어있다 → 평균 소득 계산이 틀림 ◦ date 컬럼이 숫자로 읽힌다 → 월별 분석 자체가 불가능

    3종 세트를 먼저 보면 이런 함정을 미리 잡을 수 있음.

  • 🖨️ 출력 결과

    멋사 그로스 마케팅 부트캠프 수강생 Pandas 출력 결과

2. 데이터 꺼내기(조건/필터링)

함수

기준

예시

df.loc[행, 열]

이름(라벨) · 조건

df.loc[df['age'] > 25]

df.iloc[행, 열]

숫자 순서(0부터)

df.iloc[0:5]

2-1. loc : 이름과 조건으로 선택

# 특정 컬럼 선택(열)
df.loc[:, 'age']                      # 모든 행의 age 컬럼
df.loc[:, ['name', 'age']]            # 여러 컬럼
# 조건으로 행 필터링 ← 실무에서 가장 자주 씁니다
df.loc[df['service'] == '멜론']       # 멜론 사용자만
df.loc[df['age'] >= 25]                # 25살 이상
# AND 조건 (&) — 둘 다 만족
df.loc[(df['age'] >= 25) & (df['service'] == '멜론')]

조건이 여러 개면 각각 괄호()로 감싸야 한다.

# OR 조건 (|) — 하나라도 만족
df.loc[(df['service'] == '멜론') | (df['service'] == '스포티파이')]
# 값 수정 — 조건에 맞는 행의 값을 바꿀 때
df.loc[df['satisfaction'] >= 8, 'grade'] = 'VIP'
# 그 다음 조건에 맞는 것만 덮어쓰기
df.loc[df['satisfaction'] >= 8, 'grade'] = 'VIP'
df.loc[df['satisfaction'] < 5,  'grade'] = '이탈위험'

해당 값 삭제

df.loc[df['satisfaction'] >= 8, 'grade'] = None

만약 grade라는 컬럼이 처음부터 없었다면…? 조건에 안 걸리는 행은 자동으로 NaN이 들어감. 그래서 모든 경우를 빠짐없이 커버하는 조건을 써야 빈 값 없이 채울 수 있다. 이미 값이 있었을 경우에는 해당 값만 수정됨

# 컬럼 전체 값을 삭제하고 싶다면
df['grade'] = None
# 컬럼 자체를 삭제하고 싶다면
df.drop(columns=['grade'])          # 원본 유지, 결과만 반환
df.drop(columns=['grade'], inplace=True)   # 원본에 바로 적용

2-2. iloc : 순서(번호, index)로 선택

df.iloc[0]          # 첫 번째 행
df.iloc[-1]         # 마지막 행
df.iloc[0:5]        # 0,1,2,3,4번 행 (끝 미포함!)
df.iloc[0:10, 0:3]  # 앞 10행 × 앞 3열
  • loc vs iloc 차이

    loc

    iloc

    기준

    이름 / 조건

    숫자 순서

    끝 포함?

    포함

    미포함

    주로 쓸 때

    조건 필터링

    몇 번째 행인지 알 때

  • 끝 포함이란 [:5]일 때 5번째를 포함하는지 안 하는지

➡️ 마케터는 loc를 더 많이 쓴다. 실무에서 자주 하는 작업은 다음과 같은 것들이기 때문..

  • "캠페인에 반응한 고객만 뽑아줘" → 조건 필터링 → loc

  • "이탈 고객 중 30대만 보고 싶어" → AND 조건 → loc

  • "만족도 8점 이상 고객에게 VIP 태그 달기" → 값 수정 → loc따라서 iloc는 데이터를 샘플로 빠르게 확인하거나, 마지막 N개 행을 볼 때 주로 씀.

2-3. 연습문제

Q1. loc로 '스포티파이' 사용자만 골라내기

df.loc[df['service']=='스포티파이']

Q2. iloc로 마지막 3행만 보기

df.iloc[-3:] or df.iloc[7:10] ➡️ - 쓰면 뒤에서부터 찾을 수 있음

Q3. loc로 age > 30 이고 grade == '일반'인 행 찾기

df.loc[(df['age']>30)&(df['grade']=='일반')]

🖨️ 출력 결과

멋사 부트캠프 수강생 TIL 학습 일기

3. 결측치 (Missing Value)

  • 결측치를 없애야하는 이유:

    결측치를 그냥 두면 pandas에서는 그 행을 계산에서 자동 제외함. 조용히 제외되기 때문에 내가 모르는 사이에 일부 고객은 분석에서 빠지는 상황 발생. 결측치 처리는 데이터를 고치는 게 아니라 분석 대상에서 빠지는 사람이 없도록 하는 것임.

  • 처리 방법과 선택 기준

    • 방법 1: 행 제거 — 결측 비율이 낮을 때

      df.dropna(subset=['likes'])
      

    • 방법 2: 문자열 → '미응답'으로 채우기

      df['service'].fillna('미응답')
      

      판다스 함수 대부분은 원본은 건드리지 않고 결과만 반환함. 원본에 적용하려면 항상 df = ...로 다시 저장하거나 inplace=True를 써야 함.

      코드

      원본 변경

      df.dropna()

      x

      df = df.dropna()

      o

      df.dropna(inplace=True)

      o


    • 방법 3: 숫자 → 중앙값으로 채우기 ← 실무에서 가장 자주 씀.➡️ 평균 말고 중앙값 쓰는 이유: 소득/구매금액/체류시간 같은 마케팅 데이터는 한쪽으로 치우친 경우가 많기 때문임.

      df['income'] = df['income'].fillna(df['income'].median())
      #Carol(None), Hank(None) → 전체 income 중앙값으로 채움
      

    • 방법 4: 그룹별 중앙값으로 채우기 ← 가장 정교한 방법➡️ 그룹별 중앙값이 더 좋은 이유: 각 그룹의 특성을 살릴 수 있기 때문. 전체 중앙값 하나로 채우면 그룹 간 차이가 사라짐.

       df['income'] = df['income'].fillna(
       df.groupby('service')['income'].transform('median'))
       # 같은 서비스 사용자들의 중앙값으로 채움
       # Carol(애플뮤직) → 애플뮤직 사용자 income 중앙값
       # Hank(멜론)      → 멜론 사용자 income 중앙값
      

4. 이상치(Outlier)

  • 이상치란?: 다른 값들과 동떨어진, 비정상적인 값

  • 이상치 확인 함수

    함수

    하는 일

    df['col'].describe()

    최솟값·최댓값·평균 등 확인

    df['col'].quantile(0.25)

    하위 25% 값(Q1)

    df['col'].quantile(0.75)

    상위 75% 값(Q3)

    df[조건].copy()

    조건에 맞는 행만 복사해서 새 DataFrame 만들기

  • 이상치 처리해야하는 이유: 이상치는 평균을 왜곡시킨다. 특히 마케팅 리포트에서 자주 쓰는 평균 지표는 이상치 하나에 크게 흔들림. 또한 이상치 처리 전, 실제 고객 행동인지 데이터 오류인지를 먼저 판단하는 게 중요함.

  • 코드

    # 기초 통계로 먼저 확인
    df['age'].describe()    # max가 말도 안 되게 크면 이상치!
    
    # IQR 방식으로 이상치 기준 계산
    Q1  = df['age'].quantile(0.25)
    Q3  = df['age'].quantile(0.75)
    IQR = Q3 - Q1
    
    upper = Q3 + 1.5 * IQR   # 이 값보다 크면 이상치
    
    # 이상치 확인 후 제거
    df_clean = df[df['age'] <= upper].copy()
    
  • 🖨️ 출력 결과


5. 파생변수 만들기

  • 마케터에게 파생변수란?

    : 데이터에는 "나이(출생연도)", "총 구매금액(카테고리별 금액들)", "이탈 위험(만족도)"처럼 가공 전 원재료 형태로 들어있는 경우가 많음.

    파생변수는 이 원재료를 마케터가 실제로 쓸 수 있는 지표로 바꾸는 작업임.

  • 방법 1: 계산으로 새 컬럼

    df['income_만원'] = df['income'] / 10000
    
  • 방법 2: 조건으로 새 컬럼 loc 사용

    df['grade'] = '일반'
    df.loc[df['satisfaction'] >= 8, 'grade'] = 'VIP'
    df.loc[df['satisfaction'] <= 3, 'grade'] = '이탈위험'
    
  • 방법 3: pd.cut — 숫자를 구간으로 나누기

    df['age_group'] = pd.cut(
    df['age'],
    bins=[0, 29, 39, 49, 100],
    labels=['20대', '30대', '40대', '50대+']
    )
    
  • 방법 4: 열 방향 합산 (axis=1)

    df['engagement'] = df[['likes', 'satisfaction']].sum(axis=1)
    # likes + satisfaction 을 합산한 참여도 지표
    
    • axis=1은 "각 행에서 열 방향으로 계산"이라는 뜻으로, 구매 카테고리 금액들을 합산할 때처럼 한 행 안에서 여러 컬럼을 더할 때 사용함

  • 방법 5: 방법 5: True/False 활용

    df['is_high_income'] = df['income'] >= 5000
    # income 5000만원 이상이면 True, 아니면 False
    

6. 그룹별 집계(Group by)

  • SQL의 GROUP BY와 같다. 서비스별 평균 만족도 같은 걸 계산할 때 사용

    함수

    하는 일

    df.groupby('col')['target'].mean()

    그룹별 평균

    df.groupby('col')['target'].count()

    그룹별 행 개수

    df.groupby('col').agg({...})

    그룹별 여러 통계 한번에

    .sort_values(ascending=False)

    내림차순 정렬

    .round(1)

    소수점 1자리로 반올림

  • 서비스별 평균 만족도

    df.groupby('service')['satisfaction'].mean()
    
  • 서비스별 여러 통계 한번에

    df.groupby('service').agg({
          'satisfaction': 'mean',
          'income': 'mean',
          'name': 'count'
          })
    
  • 정렬 + 반올림

    df.groupby('service')['satisfaction'].mean().round(1).sort_values(ascending=False)
    
  • 🖨️ 출력 결과

    멋쟁이사자처럼 그로스 마케팅 수강생 SQL 배운 내용 정리

0413 회고

Liked, 무엇이 좋았다

Learned, 무엇을 배웠다

Long for, 앞으로 무엇을 해볼 것이다

전공 수업 및 ADsP 자격증 준비를 하며 이상치, 결측치에 대한 개념은 알고 있었는데 이걸 실제 데이터에서 처리하는 방법을 배우게 되어 좋았다.

오늘은 pandas를 이용해 loc로 데이터 필터링 하기, 데이터의 이상치(IQR 방식을 사용해 Q3 + 1.5*IQR로 기준 판단), 결측치 보완(전체 데이터 중 5% 미만일 땐 삭제(dropna), 결측치 자체가 데이터가 되는 경우 미응답으로 채움(fillna), 중앙값으로 채우기)하는 법을 배웠다.

아직은 강사님의 코드를 따라 치는 수준에 불과하니 내 것으로 만드는 연습을 해야할 것 같다. 수업에서 작성한 코드 뿐만 아니라 데이터를 사용해 이것저것 입력해보면서 각 함수의 특징을 보면 더 이해하기 수월할 것 같다.


이터 분석에서 가장 많은 시간을 쓰는 건 모델이 아니라 데이터를 다듬는 과정이에요. 결측치와 이상치 처리는 어떤 데이터 분석 프로젝트에서도 피할 수 없는 첫 번째 관문이에요.

오늘 소개한 수강생처럼 개념만 아는 것에서 그치지 않고, 실제 코드로 직접 써보고 기록하는 과정이 쌓이면 그게 바로 실력이 돼요. 마케터로서 데이터를 자신 있게 다루는 그날까지, 멋쟁이사자처럼이 함께할게요.

멋쟁이사자처럼 그로스 마케팅 부트캠프 상세보기
Share article