데이터 전처리과정에서 DataFrame을 많이 다루게 돼서 이참에 기본적이고 핵심적인 함수들을 한번 정리하고 가보도록 하겠습니다.
예제 데이터 준비하기
import pandas as pd
import numpy as np
# 예제용 샘플 데이터프레임
df = pd.DataFrame({
'제품명': ['A-1', 'B-1', 'A-1', 'C-1', 'B-2', 'D-1'],
'카테고리': ['가전', '가구', '가전', '가전', '가구', '주방'],
'가격': [100, 150, 100, 120, 180, np.nan],
'태그': [['신상', '인기'], '할인', ['신상', '인기'], '추천', '할인', np.nan]
}, index=['p1', 'p2', 'p3', 'p4', 'p5', 'p6'])
print("--- 원본 데이터 ---")
print(df)
[실행 결과]
제품명 카테고리 가격 태그
p1 A-1 가전 100.0 [신상, 인기]
p2 B-1 가구 150.0 할인
p3 A-1 가전 100.0 [신상, 인기]
p4 C-1 가전 120.0 추천
p5 B-2 가구 180.0 할인
p6 D-1 주방 NaN NaN
1. columns : 열 이름 확인과 변경
데이터프레임의 모든 열 이름을 확인하거나 변경할 때 사용합니다. 어떤 열들이 있는지 확인하고, 필요하다면 이름을 바꿀 수 있습니다.
[사용 예시]
# 현재 열 이름 확인하기
print(df.columns)
# 열 이름 전체를 영어로 변경하기
df_renamed = df.copy() # 원본 데이터는 소중하니까 복사해서 사용해요!
df_renamed.columns = ['Product', 'Category', 'Price', 'Tags']
print("\n--- 열 이름 변경 후 ---")
print(df_renamed.head(2))
[실행 결과]
Index(['제품명', '카테고리', '가격', '태그'], dtype='object')
--- 열 이름 변경 후 ---
Product Category Price Tags
p1 A-1 가전 100.0 [신상, 인기]
p2 B-1 가구 150.0 할인
2. loc : 이름으로 데이터 선택하기
라벨(이름) 기반으로 행과 열을 선택할 수 있습니다. loc[행_라벨, 열_라벨] 형식으로 사용하고 사람이 보고 이해가기 가장 직관적인 방법이라고 할 수 있습니다.
[사용 예시]
# 1) 특정 행 선택하기 (p1 행의 모든 정보)
print(df.loc['p1'])
# 2) 여러 행과 특정 열 선택하기 (p1, p4 행의 제품명, 가격 정보)
print("\n", df.loc[['p1', 'p4'], ['제품명', '가격']])
# 3) 조건에 맞는 행 선택하기 (카테고리가 '가구'인 모든 데이터)
print("\n", df.loc[df['카테고리'] == '가구'])
[실행 결과]
제품명 A-1
카테고리 가전
가격 100.0
태그 [신상, 인기]
Name: p1, dtype: object
제품명 가격
p1 A-1 100.0
p4 C-1 120.0
제품명 카테고리 가격 태그
p2 B-1 가구 150.0 할인
p5 B-2 가구 180.0 할인
3. iloc : 위치로 데이터 선택하기
0부터 시작하는 정수 위치(순서)로 데이터를 선택합니다. 코드로 특정 위치의 데이터를 가져올 때 매우 유용합니다.
[사용 예시]
# 1) 첫 번째 행 선택하기 (0번 인덱스)
print(df.iloc[0])
# 2) 여러 행과 열 슬라이싱하기 (0~2번 행, 1~2번 열)
print("\n", df.iloc[0:3, 1:3])
[실행 결과]
제품명 A-1
카테고리 가전
가격 100.0
태그 [신상, 인기]
Name: p1, dtype: object
카테고리 가격
p1 가전 100.0
p2 가구 150.0
p3 가전 100.0
4. concat : 데이터프레임 합치기
여러개로 나뉜 데이터를 하나로 합칠때 사용합니다.
[사용 예시]
# 추가할 새로운 데이터
new_product = pd.DataFrame({'제품명': ['E-1'], '카테고리': ['생활'], '가격': [80], '태그': ['특가']})
# 기존 데이터프레임(df) 아래에 새로운 데이터(new_product)를 합치기
df_combined = pd.concat([df, new_product], ignore_index=True) # ignore_index=True 로 인덱스를 새로 부여
print(df_combined.tail(3))
[실행 결과]
제품명 카테고리 가격 태그
4 B-2 가구 180.0 할인
5 D-1 주방 NaN NaN
6 E-1 생활 80.0 특가
5. drop_duplicates : 중복 데이터 제거하기
중복된 행을 제거합니다. subset으로 특정 열 기준 중복 검사가 가능하고, keep으로 어떤 중복값을 남길지 정할 수 있습니다.
(p1, p3가 모든 데이터가 동일한 중복 행이라고 가정하겠습니다.)
[사용 예시]
# 1) 기본 : 모든 열이 동일한 행 제거 (첫 번째 값 남김)
print(df.drop_duplicates())
# 2) keep='last' : 중복된 값 중 마지막 값 남기기
print("\n", df.drop_duplicates(keep='last'))
# 3) subset=['카테고리'] : '카테고리' 열 기준으로 중복 제거
print("\n", df.drop_duplicates(subset=['카테고리']))
[실행 결과]
// (기본) p3 행이 제거됨
제품명 카테고리 가격 태그
p1 A-1 가전 100.0 [신상, 인기]
p2 B-1 가구 150.0 할인
p4 C-1 가전 120.0 추천
p5 B-2 가구 180.0 할인
p6 D-1 주방 NaN NaN
// (keep='last') p1 행이 제거됨
제품명 카테고리 가격 태그
p2 B-1 가구 150.0 할인
p3 A-1 가전 100.0 [신상, 인기]
p4 C-1 가전 120.0 추천
p5 B-2 가구 180.0 할인
p6 D-1 주방 NaN NaN
// (subset) 카테고리별로 처음 나타나는 행만 남김
제품명 카테고리 가격 태그
p1 A-1 가전 100.0 [신상, 인기]
p2 B-1 가구 150.0 할인
p6 D-1 주방 NaN NaN
6. reset_index : 인덱스 재설정하기
데이터 정제 후 뒤죽박죽인 인덱스를 0부터 시작하는 깔끔한 정수 인덱스로 초기화합니다.
[사용 예시]
# 1) 기본 : 기존 인덱스('p1', 'p2'...)가 'index'라는 새로운 열로 들어감
print(df.reset_index().head(2))
# 2) drop=True : 기존 인덱스를 열로 추가하지 않고 그냥 버림
print("\n", df.reset_index(drop=True).head(2))
[실행 결과]
index 제품명 카테고리 가격 태그
0 p1 A-1 가전 100.0 [신상, 인기]
1 p2 B-1 가구 150.0 할인
제품명 카테고리 가격 태그
0 A-1 가전 100.0 [신상, 인기]
1 B-1 가구 150.0 할인
7. insert : 원하는 위치에 열 삽입하기
원하는 위치에 열을 삽입합니다. insert(위치, 열_이름, 데이터) 형식으로 사용합니다.
[사용 예시]
# 1번 위치(두 번째)에 '판매량' 열 삽입하기
df_inserted = df.copy()
sales_data = [50, 30, 80, 120, 40, 10]
df_inserted.insert(1, '판매량', sales_data)
print(df_inserted.head(2))
[실행 결과]
제품명 판매량 카테고리 가격 태그
p1 A-1 50 가전 100.0 [신상, 인기]
p2 B-1 30 가구 150.0 할인
8. rename : 열 이름 부분 변경하기
columns 속성은 전체 이름을 바꿀 때, rename 속성은 특정 열의 이름만 골라서 바꿀 때 편리합니다.
[사용 예시]
# '제품명' -> '상품명', '가격' -> '판매가'로 변경
df_renamed_part = df.rename(columns={'제품명': '상품명', '가격': '판매가'})
print(df_renamed_part.head(2))
[실행 결과]
상품명 카테고리 판매가 태그
p1 A-1 가전 100.0 [신상, 인기]
p2 B-1 가구 150.0 할인
9. explode : 리스트 데이터를 행으로 펼치기
하나의 셀에 여러 값이 리스트로 담겨있을 때, 각 값을 개별 행으로 분리해주는 함수입니다.
[사용 예시]
# '태그' 열의 리스트 값을 각각의 행으로 펼치기
df_exploded = df.explode('태그')
print(df_exploded)
[실행 결과]
제품명 카테고리 가격 태그
p1 A-1 가전 100.0 신상
p1 A-1 가전 100.0 인기
p2 B-1 가구 150.0 할인
p3 A-1 가전 100.0 신상
p3 A-1 가전 100.0 인기
p4 C-1 가전 120.0 추천
p5 B-2 가구 180.0 할인
p6 D-1 주방 NaN NaN
10. isna/notna : 결측치 확인하기
데이터가 결측치인지 아닌지를 boolean 값으로 반환합니다. 보통 .sum()과 함께 사용하여 결측치 개수를 파악합니다.
[사용 예시]
# isna() : 결측치면 True, 아니면 False
print(df.isna())
# isna().sum() : 열별 결측치 개수 파악
print("\n--- 열별 결측치 개수 ---")
print(df.isna().sum())
[실행 결과]
제품명 카테고리 가격 태그
p1 False False False False
p2 False False False False
p3 False False False False
p4 False False False False
p5 False False False False
p6 False False True True
--- 열별 결측치 개수 ---
제품명 0
카테고리 0
가격 1
태그 1
dtype: int64
11. fillna : 결측치 채우기
결측치를 특정 값으로 채워 데이터를 깔끔하게 만듭니다.
[사용 예시]
# '가격'의 결측치는 0으로, '태그'의 결측치는 '정보없음'으로 채우기
df_filled = df.copy()
df_filled['가격'] = df_filled['가격'].fillna(0)
df_filled['태그'] = df_filled['태그'].fillna('정보없음')
print(df_filled.tail(1)) # 마지막 행 확인
[실행 결과]
제품명 카테고리 가격 태그
p6 D-1 주방 0.0 정보없음
12. iterrows : 행 단위로 반복하기
데이터프레임의 행을 하나씩 순회하며 (인덱스, 행 데이터) 쌍을 반환합니다. for 문과 함께 사용하면 각 행의 데이터에 쉽게 접근할 수 있습니다.
[사용 예시]
# 각 행을 순회하며 제품명과 카테고리를 출력
for index, row in df.iterrows():
product_name = row['제품명']
category = row['카테고리']
print(f"인덱스 '{index}' : {product_name} 제품은 {category} 카테고리에 속합니다.")
[실행 결과]
인덱스 'p1' : A-1 제품은 가전 카테고리에 속합니다.
인덱스 'p2' : B-1 제품은 가구 카테고리에 속합니다.
인덱스 'p3' : A-1 제품은 가전 카테고리에 속합니다.
인덱스 'p4' : C-1 제품은 가전 카테고리에 속합니다.
인덱스 'p5' : B-2 제품은 가구 카테고리에 속합니다.
인덱스 'p6' : D-1 제품은 주방 카테고리에 속합니다.
13. list와의 자유로운 변환
Pandas의 열(series)은 파이썬의 list와 쉽게 변환할 수 있어 데이터 활용도를 높여줍니다.
[사용 예시]
# '카테고리' 열을 리스트로 만들기
category_list = df['카테고리'].tolist()
print(category_list)
[실행 결과]
['가전', '가구', '가전', '가전', '가구', '주방']