Fullstack 67

heo4·2026년 7월 21일

Fullstack

목록 보기
22/70

풀스택

Pandas 실전 활용 - 필터링과 결측치 처리

국비과정에서 배운 Pandas의 불리언 인덱싱(조건 필터링)과 결측치 처리를 정리했다. 데이터 분석에서 가장 실전적으로 쓰이는 파트다.

1. 데이터 필터링 (Boolean Indexing)

조건을 걸어 원하는 행(Row)만 추출하는 방법이다. 조건 결과가 True인 데이터만 남긴다고 해서 불리언 인덱싱이라 부른다.

연산자의미예시
==같다df['class'] == 'Business'
!=다르다df['airline'] != 'Korean Air'
>, <크다, 작다df['price'] > 500000
&AND (그리고)(조건1) & (조건2)
\|OR (또는)(조건1) \| (조건2)

2. 단일 조건 필터링

가장 기본적인, 조건 하나로 걸러내는 방식이다.

import pandas as pd

# 1. 데이터 불러오기
df = pd.read_csv('Clean_Dataset.csv')

# 2. 'Business' 좌석 등급만 골라내기
# df[조건식] 형태로 작성
business_df = df[df['class'] == 'Business']

print("--- 비즈니스석 데이터 상위 5행 ---")
print(business_df.head())
print(f"전체 건수: {len(business_df)}건")

3. 다중 조건 필터링

여러 조건을 동시에 만족하는 데이터를 찾을 때 쓴다.

⚠️ 조건마다 반드시 괄호 ()를 쳐야 한다. 괄호 없이 &나 |를 쓰면 연산자 우선순위 문제로 에러가 난다.

import pandas as pd

df = pd.read_csv('Clean_Dataset.csv')

# 항공사가 'AirAsia'이면서 가격이 6,000원 이하인 항공권 찾기
condition = (df['airline'] == 'AirAsia') & (df['price'] <= 6000)
target_df = df[condition]

print("--- AirAsia & 6000원 이하 데이터 ---")
print(target_df.head())

4. 결측치(Missing Value) 처리하기

데이터에 값이 비어 있는 상태인 NaN(Not a Number)을 처리하는 과정이다.

4-1) 결측치가 포함된 데이터프레임 만들어보기

먼저 실습용으로 일부러 구멍(NaN)을 뚫어놓은 데이터를 만들어본다.

import pandas as pd
import numpy as np

# 1. 실습용 '구멍 난' 데이터 생성
data = {
    '이름': ['자바', '바미', '초코', np.nan],
    '나이': [3, np.nan, 5, 1],
    '몸무게': [4.5, 3.2, np.nan, np.nan],
    '소속': [np.nan, np.nan, np.nan, np.nan]  # 모든 값이 결측치인 컬럼
}
df = pd.DataFrame(data)

print("--- 원본 데이터 (NaN 확인) ---")
print(df)

dropna() — "불량품은 버린다"

결측치가 있는 행이나 열을 삭제하는 도구다. how 옵션으로 얼마나 엄격하게 지울지 정한다.

  • how='any' (기본값): 행에 결측치가 하나라도 있으면 삭제
  • how='all': 행의 모든 값이 결측치여야 삭제
# 하나라도 NaN이 있으면 삭제 (대부분의 행이 사라질 수 있음)
df_any = df.dropna(how='any')

# 모든 값이 NaN인 행만 삭제 (여기서는 삭제되는 행이 없음)
df_all = df.dropna(how='all')

fillna() — "빈칸을 메운다"

삭제 대신 적절한 값으로 채워 넣는 도구다. 컬럼마다 다른 값으로 채우고 싶으면 딕셔너리로 지정할 수 있다.

import pandas as pd
import numpy as np

data = {
    '이름': ['자바', '바미', '초코', np.nan],
    '나이': [3, np.nan, 5, np.nan],
    '몸무게': [4.5, 3.2, np.nan, np.nan],
    '소속': ["한코딩", np.nan, np.nan, np.nan]
}

df = pd.DataFrame(data)

df_custom = df.fillna({'이름': '이름 없음', '나이': 0, '몸무게': 0, "소속": "무소속"})

print(df_custom)

4-2) 결측치 확인하기

값을 채우거나 삭제하기 전에, 어떤 컬럼에 결측치가 얼마나 있는지 먼저 파악해야 한다.

import pandas as pd

df = pd.read_csv('Clean_Dataset.csv')

# 각 컬럼별로 비어있는 데이터가 몇 개인지 합계 출력
print("--- 컬럼별 결측치 개수 ---")
print(df.isnull().sum())
import pandas as pd
import numpy as np

data = {
    '이름': ['자바', '바미', '초코', np.nan],
    '나이': [3, np.nan, 5, np.nan],
    '몸무게': [4.5, 3.2, np.nan, np.nan],
    '소속': ['SBS', np.nan, np.nan, np.nan]
}

df = pd.DataFrame(data)

print(df.isnull().sum())

isnull()은 각 셀이 결측치면 True, 아니면 False를 반환하고, 여기에 .sum()을 붙이면 컬럼별로 결측치 개수를 셀 수 있다.

4-3) 결측치 삭제 또는 채우기

지시사항에 따라 삭제(dropna)할지, 특정 값으로 채울지(fillna) 결정한다.

import pandas as pd

df = pd.read_csv('Clean_Dataset.csv')

# 방법 1: 결측치가 하나라도 있는 행을 통째로 삭제 (axis=0)
df_drop = df.dropna(axis=0)

# 방법 2: 결측치를 특정 값(예: 0)으로 채우기
df_fill_zero = df.fillna(0)

# 방법 3: 결측치를 해당 컬럼의 평균값으로 채우기 (가장 많이 권장됨)
price_mean = df['price'].mean()
df['price'] = df['price'].fillna(price_mean)

print("--- 결측치 처리 완료 ---")
import pandas as pd
import numpy as np

data = {
    '이름': ['자바', '바미', '초코', np.nan],
    '나이': [3, np.nan, 5, np.nan],
    '몸무게': [4.5, 3.2, np.nan, np.nan],
    '소속': ['SBS', np.nan, np.nan, np.nan]
}

df = pd.DataFrame(data)

# 방법 1: 결측치가 하나라도 있는 행을 통째로 삭제
df_drop = df.dropna(axis=0)

# 방법 2: 결측치를 특정 값(예: 0)으로 채우기
df_fill_zero = df.fillna(0)

print("--- 결측치 처리 완료 ---")

💡 무조건 삭제(dropna)하면 데이터 손실이 크므로, 실무에서는 컬럼의 평균/중앙값 등으로 채우는 fillna가 더 자주 권장된다.


5. 연습문제

Clean_Dataset.csv를 사용해서, 출발 도시(source_city)가 'Delhi'이고 도착 도시(destination_city)가 'Mumbai'인 데이터만 추출한 뒤, 가격(price) 높은 순서로 상위 10개를 출력하기.

정답 코드 보기
import pandas as pd

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

# 1. 조건 지정
condition = (df['source_city'] == 'Delhi') & (df['destination_city'] == 'Mumbai')

# 2. 필터링된 데이터프레임 생성
filtered_df = df[condition]

# 3. 필터링된 데이터에서 가격이 높은 순서대로 정렬
result = filtered_df.sort_values(by='price', ascending=False)

# 4. 출력
print(result.head(10))

다른 정답

import pandas as pd

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

filtered_df = df[(df['source_city'] == 'Delhi') & (df['destination_city'] == 'Mumbai')]

result_df = filtered_df.sort_values(by='price', ascending=False)

print(result_df.head(10)[['source_city','destination_city','price']])

결과 값

      source_city destination_city  price
206787       Delhi           Mumbai  95657
206878       Delhi           Mumbai  91575
210742       Delhi           Mumbai  90281
210743       Delhi           Mumbai  90281
207626       Delhi           Mumbai  87929
208388       Delhi           Mumbai  87817
206877       Delhi           Mumbai  86776
206875       Delhi           Mumbai  86137
206876       Delhi           Mumbai  86137
208731       Delhi           Mumbai  85801

마무리

  • 다중 조건 필터링에서는 각 조건을 괄호로 감싸는 것을 절대 잊지 말자. df[(조건1) & (조건2)] 형태를 기본 틀로 외워두면 편하다.
  • 결측치 처리는 isnull().sum()으로 먼저 현황을 파악한 뒤, 상황에 맞게 dropna()(삭제) 또는 fillna()(채우기)를 선택한다.
  • 특히 수치형 컬럼은 무작정 삭제하기보다 평균값으로 채우는 방식이 데이터 손실을 줄이면서도 합리적인 경우가 많다.

Python 데이터 시각화 정리 - Matplotlib & Seaborn

국비과정에서 배운 데이터 시각화를 정리했다. 환경 설정(한글 폰트)부터 막대 그래프, 히스토그램, 박스 플롯까지 AICE 시험에서 자주 나오는 차트 위주로 다룬다.

1. 환경 설정: 모듈 가져오기 & 한글 깨짐 방지

파이썬 시각화의 기본은 Matplotlib과 세련된 디자인의 Seaborn이다. 한국어 데이터를 다룰 땐 한글 폰트 설정이 필수다.

import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns

# 1. 데이터 불러오기
df = pd.read_csv('Clean_Dataset.csv', index_col=0)

# 2. 한글 깨짐 방지 설정 (Windows 기준)
plt.rc('font', family='Malgun Gothic')
plt.rcParams['axes.unicode_minus'] = False  # 마이너스 기호 깨짐 방지

print("시각화 준비 완료!")

💡 한글 폰트 설정을 빼먹으면 그래프의 한글 글자가 전부 네모(□)로 깨져서 나온다. 한국어 라벨을 쓸 계획이면 시각화 코드의 맨 앞에 항상 넣어두는 습관을 들이자.


2. Matplotlib & Seaborn 필수 메소드

분류메소드 (함수)역할 및 목적주요 파라미터
기본 설정plt.rc() / plt.rcParams한글 폰트, 마이너스 기호 깨짐 등 설정family(글꼴), size(글자 크기)
기본 설정plt.figure()그래프를 그릴 도화지(Canvas) 준비figsize=(가로, 세로) (단위: inch)
비교 (범주)sns.barplot()막대 그래프. 그룹별 평균값 비교x, y, data, palette(색상)
비교 (범주)sns.countplot()항목별 데이터 개수를 자동으로 세어줌x, data, hue(추가 분류)
분포 (수치)sns.histplot()히스토그램. 데이터가 어디에 몰려 있는지 확인bins(막대 개수), kde(곡선 여부)
분포 (수치)sns.boxplot() ⭐상자 그림. 사분위수와 이상치 확인 (시험 빈출)x, y, data
관계sns.scatterplot()산점도. 두 숫자 데이터 간 상관관계 확인x, y, data
관계sns.heatmap() ⭐히트맵. 상관계수를 색상으로 시각화data, annot=True(숫자 표시)
꾸미기plt.title()그래프 상단에 제목 달기fontsize(글자 크기)
꾸미기plt.xlabel() / ylabel()X축/Y축에 이름(라벨) 붙이기label
꾸미기plt.xticks(rotation=45)X축 글자가 겹칠 때 각도를 회전rotation
마무리plt.show()완성된 그래프를 화면에 출력 (마침표 역할)-

막대 그래프 종합 예제

import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns

# 1. 데이터 불러오기
df = pd.read_csv('Clean_Dataset.csv')
plt.rc('font', family='Malgun Gothic')

# 2. 도화지 꺼내기
plt.figure(figsize=(12, 6))

# 3. 그림 그리기
# hue='airline'으로 색상 기준을 명시하고, legend=False로 중복 범례를 숨긴다.
sns.barplot(x='airline', y='price', data=df, hue='airline', palette='viridis', legend=False)

# 4. 이름표 붙이기
plt.title('항공사별 평균 항공권 가격 현황', fontsize=15)
plt.xlabel('항공사 이름')
plt.ylabel('평균 가격(INR)')

# 5. X축 글자 회전
plt.xticks(rotation=45)

# 6. 출력하기
plt.show()

선 그래프 관련 메소드

메소드기능주요 매개변수
plt.plot()선 그래프 그리기x, y: 데이터, label: 범례에 표시할 이름, color: 색상
plt.title()그래프 제목 설정label: 제목 텍스트, fontsize: 글자 크기
plt.xlabel()X축 라벨 설정xlabel: 축 이름
plt.ylabel()Y축 라벨 설정ylabel: 축 이름
plt.legend()범례 표시loc: 위치(best, upper right 등)
plt.show()그래프 출력없음 (마지막에 호출)

항공사별/남은 일수별 평균 가격 추이를 선 그래프로 그려보면:

import pandas as pd
import matplotlib.pyplot as plt

# 1. 데이터 불러오기
df = pd.read_csv('Clean_Dataset.csv', index_col=0)

# 2. 데이터 가공 (항공사별/남은일수별 평균 가격)
vistara = df[df['airline'] == 'Vistara'].groupby('days_left')['price'].mean()
air_india = df[df['airline'] == 'Air_India'].groupby('days_left')['price'].mean()

# 3. 그래프 그리기
plt.figure(figsize=(10, 5))

# 선 그래프 그리기
plt.plot(vistara.index, vistara.values, label='Vistara')
plt.plot(air_india.index, air_india.values, label='Air_India')

plt.title('Price Trend')
plt.xlabel('Days Left')
plt.ylabel('Avg Price')
plt.legend()

plt.show()

groupby()로 그룹별 평균을 미리 구해두고, 그 결과의 .index(x축)와 .values(y축)를 plt.plot()에 넣는 패턴이 자주 쓰인다.


3. 막대 그래프 (Bar Chart): 항목별 비교

"어느 항공사가 가장 비싼가?"처럼 그룹 간의 수치를 비교할 때 가장 좋은 차트다.

import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns

df = pd.read_csv('Clean_Dataset.csv', index_col=0)
plt.rc('font', family='Malgun Gothic')

# 항공사별 평균 가격 시각화
plt.figure(figsize=(10, 6))

# sns.barplot은 자동으로 평균을 계산해서 그려준다
sns.barplot(x='airline', y='price', data=df)

plt.title('항공사별 평균 항공권 가격')
plt.xlabel('항공사')
plt.ylabel('평균 가격')
plt.show()

다른 데이터로도 같은 패턴을 반복해서 익힐 수 있다.

import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns

df = pd.read_csv('student.csv', index_col=0)
plt.rc('font', family='Malgun Gothic')

plt.figure(figsize=(10, 6))

sns.barplot(x='name', y='age', data=df)

plt.title('이름별 평균 나이')
plt.xlabel('이름')
plt.ylabel('나이')

plt.show()

4. 히스토그램 (Histogram): 데이터의 분포 확인

"항공권 가격은 주로 어느 가격대에 몰려 있는가?"처럼 분포를 확인할 때 사용한다.

import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns

df = pd.read_csv('Clean_Dataset.csv', index_col=0)
plt.rc('font', family='Malgun Gothic')

# 전체 항공권 가격 분포 확인
plt.figure(figsize=(10, 6))

# bins는 막대의 개수, kde는 부드러운 곡선 표시 여부
sns.histplot(df['price'], bins=50, kde=True, color='skyblue')

plt.title('항공권 가격 분포도')
plt.show()

5. 박스 플롯 (Box Plot): 이상치와 분포 확인

AICE 시험에서 가장 중요하게 다루는 차트다. 최솟값, 최댓값, 중앙값, 그리고 이상치(점 모양)를 한눈에 보여준다.

import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns

df = pd.read_csv('Clean_Dataset.csv', index_col=0)
plt.rc('font', family='Malgun Gothic')

# 좌석 등급(class)별 가격 분포와 이상치 확인
plt.figure(figsize=(8, 6))

sns.boxplot(x='class', y='price', data=df)

plt.title('좌석 등급별 가격 분포 (Economy vs Business)')
plt.show()

박스 플롯 읽는 법

특징의미
상자의 높낮이평균적인 가격대 (비즈니스가 훨씬 높음)
상자의 세로 길이가격의 일관성
상자 밖의 점들예외적인 가격 (평균치를 벗어난 이상치)

6. 연습문제

Clean_Dataset.csv를 활용해서 '출발 도시(source_city)별 비행 시간(duration)의 평균'을 막대 그래프로 그리기.

  • 차트 종류: sns.barplot
  • 제목: '출발 도시별 평균 비행 시간'
  • 색상 테마: palette='Set2' 옵션 추가
정답 코드 보기
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns

df = pd.read_csv('Clean_Dataset.csv', index_col=0)

plt.figure(figsize=(10, 5))

sns.barplot(x='source_city', y='duration', data=df, hue='source_city', palette='Set1')

plt.show()

마무리

  • 어떤 목적에 어떤 차트를 쓸지 구분하는 게 핵심이다: 비교는 막대 그래프, 분포는 히스토그램/박스 플롯, 관계는 산점도/히트맵.
  • 특히 박스 플롯은 이상치까지 한눈에 보여줘서 AICE 시험에서 자주 다뤄지니 꼭 익혀두자.
  • plt.figure() → 그래프 그리기 → plt.title/xlabel/ylabel → plt.show() 순서가 기본 뼈대라는 걸 기억하면 어떤 차트를 그리든 헷갈리지 않는다.

0개의 댓글