python 데이터 전처리 실습

안장훈·2024년 12월 19일

python 공부

목록 보기
3/6

실습 데이터셋

import pandas as pd
import numpy as np
from datetime import datetime, timedelta
import random

# 데이터 크기 설정
num_samples = 1000

# 랜덤 시드 설정
np.random.seed(42)

# 랜덤 데이터 생성
user_ids = np.arange(1, num_samples + 1)
purchase_dates = [datetime(2023, 1, 1) + timedelta(days=np.random.randint(0, 60)) for _ in range(num_samples)]
product_ids = np.random.randint(100, 200, size=num_samples)
categories = np.random.choice(['Electronics', 'Books', 'Clothing', 'Home', 'Toys'], size=num_samples)
prices = np.round(np.random.uniform(5, 300, size=num_samples), 2)
quantities = np.random.randint(1, 6, size=num_samples)
total_spent = prices * quantities
ages = np.random.randint(18, 65, size=num_samples)
genders = np.random.choice(['M', 'F'], size=num_samples)
locations = np.random.choice(['New York', 'Los Angeles', 'Chicago', 'San Francisco', 'Houston', 'Dallas', 'Seattle', 'Austin', 'Miami', 'Boston'], size=num_samples)
membership_levels = np.random.choice(['Bronze', 'Silver', 'Gold', 'Platinum'], size=num_samples)
ad_spends = np.round(np.random.uniform(5, 50, size=num_samples), 2)
visit_durations = np.random.randint(10, 120, size=num_samples)

# 데이터프레임 생성
data = {
    'user_id': user_ids,
    'purchase_date': purchase_dates,
    'product_id': product_ids,
    'category': categories,
    'price': prices,
    'quantity': quantities,
    'total_spent': total_spent,
    'age': ages,
    'gender': genders,
    'location': locations,
    'membership_level': membership_levels,
    'ad_spend': ad_spends,
    'visit_duration': visit_durations
}

# 데이터프레임 완성
df = pd.DataFrame(data)


# 결측치 추가
nan_indices = np.random.choice(df.index, size=50, replace=False)
df.loc[nan_indices, 'price'] = np.nan
df.loc[nan_indices[:25], 'quantity'] = np.nan

# 중복 데이터 추가
duplicate_indices = np.random.choice(df.index, size=20, replace=False)
duplicates = df.loc[duplicate_indices]
df = pd.concat([df, duplicates], ignore_index=True)

# 아웃라이어 추가
outlier_indices = np.random.choice(df.index, size=10, replace=False)
df.loc[outlier_indices, 'price'] = df['price'] * 10
df.loc[outlier_indices, 'total_spent'] = df['total_spent'] * 10


# CSV 파일로 저장
df.to_csv('./user_purchase_data.csv', index=False)

문제1.user_purchase_data.csv 파일에는 결측치가 포함되어 있습니다. 모든 결측치를 확인하고, 결측치가 있는 행을 제거하세요.

먼저 df.info()로 전체적인 데이터프레임의 정보를 확인해보면 non-Null Count부분에서 price와 quantity 두 부분이 null값을 가지고 있음을 알수 있다.

data = pd.read_csv('temp/user_purchase_data.csv')

침착하게 데이터를 불러오고
null값을 확인하는 isna()sum()을 합쳐 null값을 집계한다. 이를 null_data로 지칭해주고 프린트 해준다.

null_data = data.isna().sum()

이제 결측치가 있는 행을 확인했으니 제거 해야한다.
isna()와 비슷하게 생긴 dropna()를 사용하면 null값인 행만 제거할수 있다.

data_droped = data.dropna()

정답풀이는 여기서 추가로 결측치가 완전히 제거 되었는지 확인하기 위해 아래와 같이 NULL값을 한번더 조회한다.

print(data_droped.isnull().sum())

문제2.purchase_date 컬럼의 데이터 타입을 문자열에서 datetime으로 변환하고, total_spent 컬럼의 데이터 타입을 정수로 변환하세요.

???
아무것도 안건들였는데 이미 데이터 타입이 datetime으로 되어 있어 황당했지만 일단 문제대로 컬럼의 데이터 타입을 문자열에서 datetime으로 변환하기 위해서 강의에서 배웠던 pd.to_datetime()으로 데이터 타입을 바꾸고 total_spent의 데이터 타입도 바꿔야 하기때문에 astype()으로 바꿔주었다.

df.total_spent = df.total_spent.astype(int)

다시 확인을 위해 df.info를 하면 아래와 같이 int32로 바뀌어 있다.

문제3.중복된 구매 데이터를 확인하고 제거하세요. 중복의 기준은 user_id, purchase_date, product_id가 동일한 행으로 합니다.

중복된 데이터를 확인하기 위해선 .duplicated(subset=)를 사용해야한다. 중복의 기준이 user_id, purchase_date, product_id이기 때문에 괄호안에 해당 컬럼을 넣는다.

duplicates = data.duplicated(subset=['user_id','purchase_date','product_id'])
print("number of duplicates:", duplicates.sum())

중복된 데이터를 확인하였으면 제거를 위해 df.drop_duplicates()을 사용한다.

data_no_duplicates = data.drop_duplicates(subset=['user_id','purchase_date','product_id'])
print("number of duplicates after cleaning:", data_no_duplicates.duplicated(subset=['user_id','purchase_date','product_id']).sum())
print(data_no_duplicates)

중복된 데이터가 제거된 것을 확인하기 위해 data_no_duplicates.duplicated(subset=['user_id','purchase_date','product_id']).sum()을 써주면 끝이다.

0개의 댓글