2026. 3. 12. 20:16ㆍ카테고리 없음

PART 2. 작업형 1유형 — 전처리·통계 계산
2-1. 결측치 처리
# 결측치 확인
df.isnull().sum()
df.isnull().sum() / len(df) * 100 # 결측 비율(%)
# 결측치 제거
df.dropna(inplace=True)
df.dropna(subset=['col'], inplace=True)
# 결측치 대체
df['col'].fillna(df['col'].mean(), inplace=True) # 평균
df['col'].fillna(df['col'].median(), inplace=True) # 중앙값
df['col'].fillna(df['col'].mode()[0], inplace=True) # 최빈값
df['col'].fillna(method='ffill', inplace=True) # 앞 값
df['col'].fillna(method='bfill', inplace=True) # 뒤 값
# 그룹별 중앙값으로 대체
df['col'] = df.groupby('group')['col'].transform(lambda x: x.fillna(x.median()))
2-2. 이상치 처리 (IQR — 가장 중요!)
# IQR 이상치 탐지 및 제거
Q1 = df['col'].quantile(0.25)
Q3 = df['col'].quantile(0.75)
IQR = Q3 - Q1
lower = Q1 - 1.5 * IQR
upper = Q3 + 1.5 * IQR
# 이상치 제거
df_clean = df[(df['col'] >= lower) & (df['col'] <= upper)]
# 이상치 캡핑 (Winsorization)
df['col'] = df['col'].clip(lower=lower, upper=upper)
# 이상치 개수 확인
outliers = df[(df['col'] < lower) | (df['col'] > upper)]
print(f'이상치 개수: {len(outliers)}')
print(f'이상치 비율: {len(outliers)/len(df)*100:.2f}%')
2-3. 데이터 변환·인코딩
# 레이블 인코딩 (순서 있는 범주형 또는 트리 모델)
le = LabelEncoder()
df['col_enc'] = le.fit_transform(df['col'])
print(le.classes_) # 인코딩 매핑 확인
# 원-핫 인코딩 (순서 없는 범주형, 선형/신경망 모델)
df = pd.get_dummies(df, columns=['col'], drop_first=True)
# drop_first=True → 다중공선성 방지
# 로그 변환
df['col_log'] = np.log1p(df['col']) # log(1+x), 0 포함 가능
# 날짜 파싱
df['date'] = pd.to_datetime(df['date'])
df['year'] = df['date'].dt.year
df['month'] = df['date'].dt.month
df['day'] = df['date'].dt.day
df['dayofweek'] = df['date'].dt.dayofweek # 0=월, 6=일
# 구간화(Binning)
df['age_group'] = pd.cut(df['age'], bins=[0,20,40,60,100],
labels=['10대이하','20-40대','40-60대','60대이상'])
2-4. 기술통계 계산 (자주 출제 패턴)
# 기본 통계
print(df['col'].mean()) # 평균
print(df['col'].median()) # 중앙값
print(df['col'].mode()[0]) # 최빈값
print(df['col'].std()) # 표준편차
print(df['col'].var()) # 분산
print(df['col'].min()) # 최솟값
print(df['col'].max()) # 최댓값
print(df['col'].quantile(0.25)) # 1사분위수
print(df['col'].quantile(0.75)) # 3사분위수
print(df['col'].skew()) # 왜도
print(df['col'].kurt()) # 첨도
# 그룹별 통계
df.groupby('group')['col'].mean()
df.groupby('group')['col'].agg(['mean','median','std','count'])
# 상위 N개 값 추출
df.nlargest(3, 'col') # 상위 3개 행
df.nsmallest(3, 'col') # 하위 3개 행
# 특정 조건 집계
df[df['col'] > 50]['target'].mean()
2-5. 데이터 병합·정렬·중복 처리
# 정렬
df.sort_values('col', ascending=False, inplace=True)
df.sort_values(['col1','col2'], ascending=[False,True])
# 중복 제거
df.drop_duplicates(inplace=True)
df.drop_duplicates(subset=['col1','col2'], inplace=True)
print(df.duplicated().sum()) # 중복 행 수
# 병합
merged = pd.merge(df1, df2, on='key', how='inner') # inner/left/right/outer
merged = pd.merge(df1, df2, left_on='a', right_on='b', how='left')
# 열 추가·삭제
df['new_col'] = df['col1'] + df['col2']
df.drop(columns=['col1'], inplace=True)
df.rename(columns={'old':'new'}, inplace=True)
2-6. 1유형 빈출 문제 패턴 (실전 템플릿)
패턴 1 — 조건 필터링 후 통계값 구하기
# 예: 특정 조건 만족하는 행의 특정 열 평균
result = df[df['age'] >= 30]['salary'].mean()
print(round(result, 2))
패턴 2 — 그룹별 상위 N개
# 예: 부서별 급여 상위 3명
result = df.groupby('dept').apply(lambda x: x.nlargest(3, 'salary'))
print(result)
패턴 3 — 결측치 처리 후 통계
df['col'] = df['col'].fillna(df['col'].median())
print(df['col'].describe())
패턴 4 — 이상치 제거 후 평균
Q1 = df['col'].quantile(0.25)
Q3 = df['col'].quantile(0.75)
IQR = Q3 - Q1
df_clean = df[(df['col'] >= Q1 - 1.5*IQR) & (df['col'] <= Q3 + 1.5*IQR)]
print(round(df_clean['col'].mean(), 2))
패턴 5 — 파생변수 생성 후 집계
df['ratio'] = df['col_a'] / df['col_b']
result = df.groupby('group')['ratio'].mean()
print(result.sort_values(ascending=False))