pandas 100제: 판다스 연습문제와 풀이 · 6장
041–050 정렬과 순위
sort_values, 여러 기준 정렬, nlargest, nsmallest, sort_index, rank, idxmax 연습문제
이 장의 목차 13개
정렬하고 순위를 매기는 문제입니다.
순위 문제의 핵심은 동점입니다. 250점이 두 명이면 기본값 average는 둘 다 1.5등, min은 둘 다 1등이고 다음 사람이 3등, dense는 둘 다 1등이고 다음 사람이 2등, first는 먼저 나온 행이 1등입니다. 시험 석차처럼 "공동 1등 다음은 3등"이면 min, 등급처럼 빈 순위 없이 이어지려면 dense를 고르세요.
준비 코드와 데이터
노트북 첫 셀에 아래 준비 코드를 붙여 넣어 실행한 뒤 문제를 푸세요.
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']
이 장 실습 노트북 내려받기 (.ipynb) — 준비 코드와 문제가 들어 있고 답 칸은 비어 있습니다. 코랩에서는 파일 → 노트 업로드로 엽니다.
준비 코드를 실행하면 df는 다음 표가 됩니다(8행 × 6열, 맨 왼쪽 숫자는 인덱스).
결과 name class kor eng math total
0 김민준 A 85 78 92 255
1 이서연 B 92 88 75 255
2 박지호 A 58 64 49 171
3 최수아 C 77 95 88 260
4 정민서 B 66 59 71 196
5 강도윤 C 90 70 66 226
6 윤하은 A 73 82 95 250
7 임시우 B 81 91 60 232
장 안의 문제는 번호 순서대로 이어집니다. 앞 문제에서 만든 열이나 변수를 다음 문제가 쓸 수 있으니, 중간부터 풀 때는 준비 코드와 앞의 필요한 문제를 먼저 실행하세요.
041. 내림차순 정렬
수학 점수가 높은 순으로 정렬하세요.
힌트 보기
sort_values("열", ascending=False).
정답 보기
Pythondf.sort_values('math', ascending=False)
결과 name class kor eng math total
6 윤하은 A 73 82 95 250
0 김민준 A 85 78 92 255
3 최수아 C 77 95 88 260
1 이서연 B 92 88 75 255
4 정민서 B 66 59 71 196
5 강도윤 C 90 70 66 226
7 임시우 B 81 91 60 232
2 박지호 A 58 64 49 171
풀이: ascending=False를 지정하면 큰 값이 먼저 옵니다. 반환 표를 저장하지 않아 원본 순서는 유지됩니다.
042. 두 기준으로 정렬
반 이름 오름차순, 같은 반 안에서는 합계 내림차순으로 정렬하세요.
힌트 보기
sort_values에 열 리스트와 ascending 리스트를 같은 순서로 넘깁니다.
정답 보기
Pythondf.sort_values(['class', 'total'], ascending=[True, False])
결과 name class kor eng math total
0 김민준 A 85 78 92 255
6 윤하은 A 73 82 95 250
2 박지호 A 58 64 49 171
1 이서연 B 92 88 75 255
7 임시우 B 81 91 60 232
4 정민서 B 66 59 71 196
3 최수아 C 77 95 88 260
5 강도윤 C 90 70 66 226
풀이: 첫 정렬 기준이 같은 행에 두 번째 기준을 적용합니다. 기준마다 방향을 따로 지정합니다.
043. 상위 n개
합계 상위 3명을 구하세요.
힌트 보기
nlargest(개수, "열").
정답 보기
Pythondf.nlargest(3, 'total')
결과 name class kor eng math total
3 최수아 C 77 95 88 260
0 김민준 A 85 78 92 255
1 이서연 B 92 88 75 255
풀이: 상위 세 행을 간단하게 고르는 방법입니다. 동점 처리 방식에 따라 정렬 후 head와 행 선택이 달라질 수 있습니다.
별도의 전체 정렬 구문 없이 상위 행을 선택할 수 있습니다.
044. 하위 n개
영어 점수 하위 2명의 name, eng를 구하세요.
힌트 보기
nlargest의 반대는 nsmallest입니다. 고른 뒤 필요한 열만 남기세요.
정답 보기
Pythondf.nsmallest(2, 'eng')[['name', 'eng']]
결과 name eng
4 정민서 59
2 박지호 64
풀이: 먼저 점수가 낮은 두 행을 고른 다음 이름과 영어 열만 남깁니다.
045. 인덱스로 되돌리기
수학 순으로 정렬한 표를 다시 인덱스 순서로 되돌리세요(앞 3행).
힌트 보기
정렬된 표에 sort_index()를 붙이면 인덱스 순서로 돌아옵니다.
정답 보기
Pythondf.sort_values('math').sort_index().head(3)
결과 name class kor eng math total
0 김민준 A 85 78 92 255
1 이서연 B 92 88 75 255
2 박지호 A 58 64 49 171
풀이: sort_index는 현재 행 위치가 아니라 원래 행 라벨을 정렬합니다.
046. 순위 매기기
합계 기준 전체 순위(1등이 가장 높은 점수) 열 rank를 만들고 name, total, rank를 보이세요.
힌트 보기
rank(ascending=False, method="min")의 결과는 실수(1.0)이므로 astype(int)로 정수로 바꿉니다.
정답 보기
Pythondf['rank'] = df['total'].rank(ascending=False, method='min').astype(int)
df[['name', 'total', 'rank']]
결과 name total rank
0 김민준 255 2
1 이서연 255 2
2 박지호 171 8
3 최수아 260 1
4 정민서 196 7
5 강도윤 226 6
6 윤하은 250 4
7 임시우 232 5
풀이: min 방식은 1·1·3처럼 다음 순위를 건너뜁니다. 동점에도 연속 순위가 필요하면 dense를 검토합니다.
method='min'은 동점자에게 같은 순위를 줍니다.
047. 반별 순위
반 안에서의 합계 순위 열 class_rank를 만들고 반·순위 순으로 보이세요.
힌트 보기
groupby("class")["total"]에 rank(...)를 붙이면 반 안에서 순위를 매깁니다.
정답 보기
Pythondf['class_rank'] = df.groupby('class')['total'].rank(ascending=False, method='min').astype(int)
df.sort_values(['class', 'class_rank'])[['class', 'name', 'total', 'class_rank']]
결과 class name total class_rank
0 A 김민준 255 1
6 A 윤하은 250 2
2 A 박지호 171 3
1 B 이서연 255 1
7 B 임시우 232 2
4 B 정민서 196 3
3 C 최수아 260 1
5 C 강도윤 226 2
풀이: 반별로 순위를 다시 계산하며 min을 명시해 동점 평균 순위를 정수로 잘라 버리는 일을 피합니다.
048. 인덱스 새로 매기기
합계 내림차순으로 정렬한 뒤 인덱스를 0부터 다시 매기세요(앞 3행).
힌트 보기
reset_index(drop=True) — drop=True가 없으면 옛 인덱스가 열로 남습니다.
정답 보기
Pythondf.sort_values('total', ascending=False).reset_index(drop=True).head(3)
결과 name class kor eng math total rank class_rank
0 최수아 C 77 95 88 260 1 1
1 김민준 A 85 78 92 255 2 1
2 이서연 B 92 88 75 255 2 1
풀이: 정렬 뒤 reset_index를 적용해야 새 번호가 점수 순서를 따릅니다.
drop=True가 없으면 기존 인덱스가 열로 남습니다.
049. 최고 점수의 주인
수학 최고 점수를 받은 학생의 이름을 구하세요.
힌트 보기
idxmax()로 최고 점수가 있는 행의 라벨을 구한 뒤, loc[라벨, "name"].
정답 보기
Pythondf.loc[df['math'].idxmax(), 'name']
결과'윤하은'
풀이: idxmax의 결과를 행 라벨로 사용해 같은 행의 이름을 읽습니다. 동점이면 첫 학생입니다.
050. 열 이름 순 정렬
열 이름을 가나다(알파벳) 순으로 정렬해 앞 2행을 보이세요.
힌트 보기
열 이름 순서를 정렬하려면 sort_index(axis=1).
정답 보기
Pythondf.sort_index(axis=1).head(2)
결과 class class_rank eng kor math name rank total
0 A 1 78 85 92 김민준 2 255
1 B 1 88 92 75 이서연 2 255
풀이: 열 라벨 정렬은 axis=1입니다. 행 순서와 열 순서의 축을 구분합니다.
axis=1은 열 방향입니다.
이 장 요약
| 문법 | 하는 일 | 문제 |
|---|---|---|
df.sort_values("열", ascending=False) | 내림차순 정렬 | 041 |
sort_values([열1, 열2], ascending=[True, False]) | 여러 기준 정렬 | 042 |
df.nlargest(n, "열") / nsmallest | 상위 / 하위 n행 | 043–044 |
df.sort_index() / sort_index(axis=1) | 인덱스 순 / 열 이름 순 | 045, 050 |
s.rank(ascending=False, method="min") | 순위(동점은 같은 순위) | 046 |
df.groupby("반")["열"].rank(...) | 그룹 안 순위 | 047 |
df.reset_index(drop=True) | 인덱스 0부터 다시 | 048 |
df.loc[s.idxmax(), "name"] | 최댓값 행의 다른 열 값 | 049 |
이 장의 점검
같은 점수의 학생을 추가한다고 가정해 순위 규칙을 설명하세요. min은 1·1·3, dense는 1·1·2, 기본 average는 1.5·1.5·3입니다.
참고: pandas 공식 문서 · 문법이 기억나지 않으면 부록 치트시트를 찾아보세요.