빅데이터 분석기사 실기 1유형 (1) — 데이터 전처리 기초
빅데이터 분석기사 실기 1유형의 기본기. pandas로 정렬·필터링·그룹별 집계까지 핵심 패턴만 추려서 정리.
빅데이터 분석기사 실기 1유형은 pandas 한 줄짜리 문제가 대부분이다. 외우는 게 아니라 손에 익혀야 하는 영역.
1유형은 어떤 시험인가?
| 항목 | 내용 |
|---|---|
| 배점 | 30점 (3문제 × 10점) |
| 형식 | 단답형 — 정수/실수 값을 출력해서 제출 |
| 시간 비중 | 전체 3시간 중 30~40분 권장 |
| 주요 도구 | pandas, numpy |
핵심은 데이터를 읽고 → 조건에 맞게 거르고 → 통계값 하나를 뽑아내는 것. 모델링도, 시각화도 없다.
import pandas as pd
import numpy as np
df = pd.read_csv("data.csv")
# 이 한 줄로 모든 1유형 문제가 시작된다
pandas 기본 — 시험장에서 가장 많이 쓰는 것들
데이터 확인 (시험장 첫 동작)
df.head() # 상위 5개
df.shape # (행, 열)
df.info() # 컬럼별 타입과 결측치 개수
df.describe() # 수치형 컬럼 요약통계
df.columns # 컬럼 이름 리스트
처음 보는 데이터셋이라면 위 다섯 줄을 무조건 먼저 친다. 컬럼명·타입·결측치 분포가 머리에 들어와야 문제를 풀 수 있다.
컬럼 선택 vs 행 선택
df["age"] # Series 한 개
df[["age", "name"]] # 여러 컬럼 (DataFrame)
df.loc[0] # 인덱스 라벨 기준 행
df.iloc[0] # 위치(0번째) 기준 행
df.loc[df["age"] > 30] # 조건 필터
loc는 라벨, iloc는 정수 위치 — 헷갈리면 loc[조건] 하나만 외워도 1유형은 충분히 친다.
정렬과 상위 N개 추출
1유형 단골 패턴: "X 컬럼 기준 내림차순으로 정렬한 뒤 상위 10개의 Y 평균"
# 단일 컬럼 내림차순
df_sorted = df.sort_values("price", ascending=False)
# 다중 컬럼 (price 내림차순, 그다음 quantity 오름차순)
df_sorted = df.sort_values(
by=["price", "quantity"],
ascending=[False, True]
)
# 상위 10개의 quantity 평균
answer = df_sorted.head(10)["quantity"].mean()
print(answer)
nlargest / nsmallest — 정렬 + head 한 줄로
# price 기준 상위 10개
df.nlargest(10, "price")
# 매출 하위 5개
df.nsmallest(5, "sales")
sort_values().head(N)과 결과는 같지만, 의도가 더 명확해서 시험 답안으로 읽기 좋다.
조건부 필터링
단일 조건
df[df["age"] >= 30]
df[df["gender"] == "F"]
df[df["city"].isin(["서울", "부산"])]
다중 조건 (괄호 잊지 말기)
# AND
df[(df["age"] >= 30) & (df["gender"] == "F")]
# OR
df[(df["city"] == "서울") | (df["city"] == "부산")]
# NOT
df[~df["city"].isin(["서울", "부산"])]
and,or,not은 못 쓴다. 반드시&,|,~이고 각 조건은 괄호로 감싸야 한다. 우선순위 때문에 안 감싸면 조용히 틀린 답이 나온다.
문자열 조건
df[df["name"].str.contains("Kim")] # 부분 일치
df[df["name"].str.startswith("이")] # 접두
df[df["name"].str.endswith(".com")] # 접미
df[df["email"].str.contains("@gmail")] # 정규식도 가능
그룹별 집계 (groupby)
1유형에서 가장 자주 나오는 패턴. 무조건 손에 익혀야 한다.
기본 형태
# 도시별 평균 나이
df.groupby("city")["age"].mean()
# 도시별 인원수
df.groupby("city").size()
df["city"].value_counts() # 동일한 결과, 더 빠름
여러 컬럼으로 묶기
# 도시 + 성별별 평균 소득
df.groupby(["city", "gender"])["income"].mean()
여러 통계량을 한 번에 (agg)
df.groupby("city")["income"].agg(["mean", "max", "min", "sum"])
# 컬럼마다 다른 함수 적용
df.groupby("city").agg({
"income": "mean",
"age": "max",
"name": "count",
})
그룹별 상위 N개 (실전 패턴)
# 도시별 매출 상위 3개 행
df.groupby("city", group_keys=False).apply(
lambda g: g.nlargest(3, "sales")
)
자주 나오는 1유형 실전 예시
예시 1. 도시별 평균이 가장 높은 도시 찾기
result = df.groupby("city")["income"].mean()
answer = result.idxmax() # 평균이 가장 높은 도시 이름
# 또는
answer = result.sort_values(ascending=False).index[0]
print(answer)
예시 2. 특정 조건을 만족하는 행 개수
# 30세 이상이면서 서울에 사는 사람 수
mask = (df["age"] >= 30) & (df["city"] == "서울")
answer = mask.sum() # True는 1, False는 0으로 합산
print(answer)
예시 3. 특정 컬럼의 상위 10% 평균
threshold = df["price"].quantile(0.9) # 상위 10% 경계값
top10 = df[df["price"] >= threshold]
answer = round(top10["price"].mean(), 2)
print(answer)
quantile(0.25), quantile(0.5), quantile(0.75)로 사분위수도 똑같이 뽑는다.
데이터 타입 변환
df["age"] = df["age"].astype(int)
df["price"] = df["price"].astype(float)
df["category"] = df["category"].astype(str)
# 날짜 변환은 별도 함수 (1유형-2에서 자세히)
df["date"] = pd.to_datetime(df["date"])
시험에서
'1234'같은 문자열을 숫자처럼 비교하려다 결과가 이상하면 90% 확률로 타입 문제다. 의심되면df.info()로 먼저 타입을 본다.
출력 형식 주의 (감점 포인트)
1유형은 출력 값 하나가 정답이다. 자료형이 안 맞으면 0점.
# 문제: "정수로 출력하시오"
print(int(answer))
# 문제: "소수점 둘째 자리까지 출력"
print(round(answer, 2))
# 문제: "리스트 형태로 출력"
print(list(answer))
문제에서 요구하는 **자료형(int, float, str)**과 소수점 자리수를 마지막에 한 번 더 확인하는 습관이 점수를 지킨다.
정리
| 패턴 | 핵심 함수 |
|---|---|
| 데이터 확인 | head, info, describe, shape |
| 정렬 | sort_values, nlargest, nsmallest |
| 필터링 | df[조건], isin, str.contains |
| 집계 | groupby, agg, value_counts |
| 통계 | mean, sum, quantile, idxmax |
| 출력 | int(), round(), print() |
1유형은 새로운 함수를 외우는 것보다 위 패턴들을 손에 새기는 게 빠르다. 다음 글에서는 결측치·이상치·스케일링·날짜 처리 등 1유형 단골 변환 기법을 정리한다.