Pandas 전처리 연습(5)

SeongGyun Hong·2024년 11월 3일

빅데이터 분석기사

목록 보기
4/16
post-thumbnail

Pandas 데이터 처리 종합 가이드

1. 데이터 선택과 필터링

1.1 기본 선택 방법

import pandas as pd
import numpy as np

# 샘플 데이터 생성
df = pd.DataFrame({
    '이름': ['김철수', '이영희', '박민수', '최지은', '김철수'],
    '나이': [25, 30, 35, 28, 25],
    '직업': ['개발자', '디자이너', '개발자', '마케터', '개발자'],
    '급여': [3500, 3200, 4000, 3300, 3500]
})

# loc를 사용한 라벨 기반 선택
개발자_데이터 = df.loc[df['직업'] == '개발자']

# iloc를 사용한 위치 기반 선택
첫_세_행 = df.iloc[0:3]

# 복합 조건 필터링
조건1 = (df['나이'] >= 30) & (df['급여'] >= 3500)
고임금_고연령 = df.loc[조건1]

1.2 고급 필터링 기법

# isin() 사용
특정_직업 = df[df['직업'].isin(['개발자', '디자이너'])]

# str.contains() 사용
이름_검색 = df[df['이름'].str.contains('김')]

# 복합 조건 필터링
복합_조건 = df.loc[
    (df['나이'] > 25) & 
    (df['급여'] >= 3500) | 
    (df['직업'] == '개발자')
]

2. 데이터프레임 값 변경 및 생성

2.1 조건부 값 변경

# np.where 사용
df['급여_등급'] = np.where(df['급여'] >= 3500, '높음', '낮음')

# apply와 lambda 사용
df['나이_그룹'] = df['나이'].apply(lambda x: '청년' if x < 30 else '중년')

# loc를 사용한 조건부 값 변경
df.loc[df['급여'] >= 4000, '급여_보너스'] = '대상'
df.loc[df['급여'] < 4000, '급여_보너스'] = '비대상'

2.2 대량 값 변경

# replace 사용
직업_매핑 = {'개발자': 'Developer', '디자이너': 'Designer', '마케터': 'Marketer'}
df['직업_영문'] = df['직업'].replace(직업_매핑)

# map 사용
df['직급'] = df['급여'].map(lambda x: '사원' if x < 3300 else '대리' if x < 3800 else '과장')

3. 중복 제거와 결측치 처리

3.1 중복 제거

# 전체 행 기준 중복 제거
df_unique = df.drop_duplicates()

# 특정 열 기준 중복 제거
df_job_unique = df.drop_duplicates(subset=['직업'])

# 여러 열 기준 중복 제거 (첫 번째 중복 유지)
df_multi_unique = df.drop_duplicates(subset=['이름', '나이'], keep='first')

3.2 결측치 처리

# 결측치가 있는 샘플 데이터 생성
df_na = df.copy()
df_na.loc[2, '급여'] = np.nan
df_na.loc[4, '직업'] = np.nan

# 결측치 확인
결측치_확인 = df_na.isnull().sum()

# 결측치 특정 값으로 대체
df_na['급여'] = df_na['급여'].fillna(df_na['급여'].mean())
df_na['직업'] = df_na['직업'].fillna('미정')

# 조건부 결측치 처리
df_na.loc[df_na['직업'].isnull(), '직업_상태'] = '확인필요'
df_na.loc[df_na['직업'].notnull(), '직업_상태'] = '확인완료'

4. 데이터 유형과 고유값 분석

4.1 데이터 유형 처리

# 데이터 유형 확인
데이터_타입 = df.dtypes

# 특정 데이터 유형 선택
숫자형_컬럼 = df.select_dtypes(include=['int64', 'float64'])
문자형_컬럼 = df.select_dtypes(include=['object'])

# 데이터 유형 변환
df['나이'] = df['나이'].astype('float64')
df['급여'] = df['급여'].astype('int32')

4.2 고유값 분석

# 각 열의 고유값 개수
고유값_개수 = df.nunique()

# 특정 열의 고유값 목록
직업_고유값 = df['직업'].unique()

# 고유값 빈도 분석
직업_빈도 = df['직업'].value_counts()
나이_빈도 = df['나이'].value_counts(normalize=True)  # 비율로 표시

5. 실전 활용 예시

5.1 데이터 전처리 파이프라인

def 데이터_전처리(df):
    # 중복 제거
    df = df.drop_duplicates()

    # 결측치 처리
    df['급여'] = df['급여'].fillna(df['급여'].mean())
    df['직업'] = df['직업'].fillna('미정')

    # 파생변수 생성
    df['급여_등급'] = np.where(df['급여'] >= df['급여'].mean(), '상위', '하위')

    # 데이터 타입 변환
    df['나이'] = df['나이'].astype('int32')

    return df

# 전처리 실행
df_cleaned = 데이터_전처리(df)

5.2 고급 분석 예시

# 직업별 평균 급여
직업별통계 = df.groupby('직업').agg({
    '급여': ['mean', 'min', 'max', 'count'],
    '나이': 'mean'
}).round(2)

# 나이대별 직업 분포
df['나이대'] = pd.cut(df['나이'], bins=[0, 25, 30, 35, 100], labels=['25세이하', '26-30세', '31-35세', '36세이상'])
나이대별직업_분포 = pd.crosstab(df['나이대'], df['직업'])

6. 문자열 처리와 고급 필터링

6.1 문자열 메서드 활용

# 소문자 변환, 문자열 길이 계산
df['description_lower'] = df['description'].str.lower()
df['description_length'] = df['description'].str.len()

# 문자열 분리와 결합
df['first_word'] = df['description'].str.split().str[0]
df['description_clean'] = df['description'].str.strip()

# 문자열 교체
df['description_modified'] = df['description'].str.replace('sauce', 'dressing')

6.2 실전 활용 예시

def 메뉴_분류(df):
    # 메뉴 설명을 기반으로 카테고리 분류
    조건_매핑 = {
        'vegetarian': df['description'].str.contains('Vegetables|Salad', case=False),
        'meat': df['description'].str.contains('Beef|Chicken|Pork', case=False),
        'pasta': df['description'].str.contains('Pasta|Spaghetti', case=False),
        'sauce_based': df['description'].str.contains('sauce', case=False)
    }
    
    for category, condition in 조건_매핑.items():
        df[f'is_{category}'] = condition
    
    return df

# 분류 실행
df_categorized = 메뉴_분류(df)

주요 팁과 주의사항

  1. loc와 iloc 사용: loc는 라벨 기반 인덱싱, iloc는 위치 기반 인덱싱에 적합
  2. 체이닝 주의: 메모리 사용 효율성을 위해 체이닝을 최소화하며 inplace=True 사용
    지양
  3. 데이터 타입 확인과 변환: 처리 속도 향상을 위해 불필요한 데이터 타입을 변경하는 것이 좋음.
profile
헤매는 만큼 자기 땅이다.

0개의 댓글