pandas 100제: 판다스 연습문제와 풀이 · 10장

091–100 실전 종합

cut, map, idxmax(axis=1), qcut, cumsum, rolling, pct_change, shift, corr, apply 종합 연습문제

5분 읽기

마지막 장은 구간 나누기, 누적·이동 평균 같은 실전 기법입니다. 91~94번은 학생 표, 95~98번은 방문자 표를 씁니다.

준비 코드

이 장의 문제는 아래 코드를 먼저 실행한 상태에서 풉니다.

Pythonimport pandas as pd
import numpy as np

df = pd.DataFrame({
    'name': ['김민준', '이서연', '박지호', '최수아', '정민서', '강도윤', '윤하은', '임시우'],
    'class': ['A', 'B', 'A', 'C', 'B', 'C', 'A', 'B'],
    'kor': [85, 92, 58, 77, 66, 90, 73, 81],
    'eng': [78, 88, 64, 95, 59, 70, 82, 91],
    'math': [92, 75, 49, 88, 71, 66, 95, 60],
})
df['total'] = df['kor'] + df['eng'] + df['math']

daily = pd.DataFrame({
    'date': pd.date_range('2026-03-01', periods=7, freq='D'),
    'visitors': [120, 135, 128, 160, 155, 210, 198],
})

091. 구간 나누기

합계를 ~199, 200~239, 240~ 세 구간(C, B, A)으로 나눈 grade 열을 만드세요.

정답 보기
Pythondf['grade'] = pd.cut(df['total'], bins=[0, 199, 239, 300], labels=['C', 'B', 'A'])
df[['name', 'total', 'grade']]
결과     name  total grade
0  김민준    255     A
1  이서연    255     A
2  박지호    171     C
3  최수아    260     A
4  정민서    196     C
5  강도윤    226     B
6  윤하은    250     A
7  임시우    232     B

092. 값 바꿔 끼우기

반 이름을 담임 이름(A: 한선생, B: 오선생, C: 문선생)으로 바꾼 teacher 열을 만드세요.

정답 보기
Pythondf['teacher'] = df['class'].map({'A': '한선생', 'B': '오선생', 'C': '문선생'})
df[['name', 'class', 'teacher']].head(4)
결과     name class teacher
0  김민준     A  한선생
1  이서연     B  오선생
2  박지호     A  한선생
3  최수아     C  문선생

093. 가장 잘한 과목

학생마다 점수가 가장 높은 과목 이름을 구하세요.

정답 보기
Pythondf.set_index('name')[['kor', 'eng', 'math']].idxmax(axis=1)
결과name
김민준    math
이서연     kor
박지호     eng
최수아     eng
정민서    math
강도윤     kor
윤하은    math
임시우     eng
dtype: object

axis=1이면 행마다 최댓값의 열 이름을 돌려줍니다.

094. 같은 인원으로 나누기

수학 점수를 사분위로 나눠 Q1~Q4를 붙이세요.

정답 보기
Pythonpd.qcut(df['math'], 4, labels=['Q1', 'Q2', 'Q3', 'Q4'])
결과0    Q4
1    Q3
2    Q1
3    Q3
4    Q2
5    Q2
6    Q4
7    Q1
Name: math, dtype: category
Categories (4, object): ['Q1' < 'Q2' < 'Q3' < 'Q4']

cut은 구간 폭, qcut은 인원(개수)을 같게 나눕니다.

095. 누적 합계

daily의 날짜별 누적 방문자 수를 구하세요.

정답 보기
Pythondaily['visitors'].cumsum()
결과0     120
1     255
2     383
3     543
4     698
5     908
6    1106
Name: visitors, dtype: int64

096. 이동 평균

3일 이동 평균 방문자 수를 구하세요.

정답 보기
Pythondaily['visitors'].rolling(3).mean().round(1)
결과0      NaN
1      NaN
2    127.7
3    141.0
4    147.7
5    175.0
6    187.7
Name: visitors, dtype: float64

앞 2일은 값이 모자라 NaN입니다.

097. 전날 대비 증감률

전날 대비 방문자 증감률(%)을 구하세요.

정답 보기
Python(daily['visitors'].pct_change() * 100).round(1)
결과0     NaN
1    12.5
2    -5.2
3    25.0
4    -3.1
5    35.5
6    -5.7
Name: visitors, dtype: float64

098. 전날 값 옆에 놓기

전날 방문자 수 열 prev와 차이 diff를 만드세요.

정답 보기
Pythondaily['prev'] = daily['visitors'].shift(1)
daily['diff'] = daily['visitors'] - daily['prev']
daily
결과        date  visitors   prev  diff
0 2026-03-01       120    NaN   NaN
1 2026-03-02       135  120.0  15.0
2 2026-03-03       128  135.0  -7.0
3 2026-03-04       160  128.0  32.0
4 2026-03-05       155  160.0  -5.0
5 2026-03-06       210  155.0  55.0
6 2026-03-07       198  210.0 -12.0

099. 과목 간 상관관계

세 과목 점수의 상관계수 표를 구하세요.

정답 보기
Pythondf[['kor', 'eng', 'math']].corr().round(2)
결과       kor   eng  math
kor   1.00  0.52  0.31
eng   0.52  1.00  0.42
math  0.31  0.42  1.00

100. 종합: 반별 리포트

반별 학생 수, 평균 합계(소수 첫째 자리), 최고 득점자 이름을 한 표로 만들고 평균 합계가 높은 반부터 보이세요.

정답 보기
Pythonreport = df.groupby('class').agg(
    학생수=('name', 'size'),
    평균합계=('total', 'mean'),
    최고득점자=('total', lambda s: df.loc[s.idxmax(), 'name']),
)
report['평균합계'] = report['평균합계'].round(1)
report.sort_values('평균합계', ascending=False)
결과       학생수  평균합계 최고득점자
class                             
C           2     243.0     최수아
B           3     227.7     이서연
A           3     225.3     김민준

집계 함수 자리에 람다를 넣으면 원하는 계산을 그룹마다 할 수 있습니다.

다음으로

개념부터 차근차근 다시 보고 싶다면 파이썬 pandas 데이터 분석 입문을 읽어 보세요. 같은 카페 매출 예제로 각 기능을 설명합니다.

전체 메뉴