본문으로 건너뛰기

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

041–050 정렬과 순위

sort_values, 여러 기준 정렬, nlargest, nsmallest, sort_index, rank, idxmax 연습문제

9분 읽기

이 장의 목차 13개

정렬하고 순위를 매기는 문제입니다.

동점이 있는 점수에 rank의 average·min·dense·first를 적용한 결과 비교
동점이 있는 점수에 rank의 average·min·dense·first를 적용한 결과 비교

순위 문제의 핵심은 동점입니다. 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 공식 문서 · 문법이 기억나지 않으면 부록 치트시트를 찾아보세요.

전체 메뉴