안녕하세요. PSYda입니다.
이번 포스팅에서는 Pandas DataFrame의 sort(정렬), rank(순위)에 대해 알아보겠습니다.
소개할 내용은 아래와 같습니다.
- DataFrame의 정렬 함수(sort_values, sort_index)
- DataFrame의 순위 측정 함수(rank)
실습에 사용한 데이터는 fifa19에 등장하는 축구선수들의 능력치 데이터 입니다.
아래에서 다운 받을 수 있습니다.
7. DataFrame의 sort, rank 함수
- sort 함수 : 데이터를 정렬하는 함수(sort_values, sort_index)
- rank 함수 : 데이터의 순위를 매기는 함수
7.1 DataFrame의 sort
DataFrame에서는 sort를 index 및 column 기준으로 sort를 할 수 있다.
- sort_values(axis = 0) : 열방향 정렬(default)
- sort_values(axis = 1) : 행방향 정렬
- sort_index(axis = 0) : 인덱스명 정렬(defualt)
- sort_index(axis = 1) : 컬럼명 정렬
정렬은 ascending 옵션을 통해 오름차순과 내림차순 정렬이 가능하다.
- ascending = True : 오름차순 정렬, 영어의 경우 a 부터
- ascending = False : 내림차순 정렬, 영어의 경우 z부터
7.1.1 sort_values() : 열방향 또는 행방향 데이터 정렬
sort_values 함수 옵션
- ascending = True : True 이면 오름차순, False이면 내림차순 정렬
- inplace = False : True 이면 정렬한 값을 DataFrame에 바로 반영
- by : 정렬할 기준 변수 지정
- na_position = last : NaN값 위치 지정, last이면 마지막, first이면 처음
- axis = 0 : 0이면 열방향 정렬, 1이면 행방향 정렬
pandas library import
import pandas as pd
from pandas import Series, DataFrame
import numpy as np
players = pd.read_csv('data/Ch6_1_fifaStats.csv', index_col = 'Name')
players.head()
ShortPassing | Dribbling | LongPassing | BallControl | |
---|---|---|---|---|
Name | ||||
L. Messi | 90.0 | 97.0 | 87.0 | 96.0 |
Cristiano Ronaldo | 81.0 | 88.0 | 77.0 | 94.0 |
Neymar Jr | 84.0 | 96.0 | 78.0 | 95.0 |
De Gea | 50.0 | 18.0 | 51.0 | 42.0 |
K. De Bruyne | 92.0 | 86.0 | 91.0 | 91.0 |
7.1.1.1 by 옵션
DataFrame에서 정렬할 변수를 지정 할 수 있다.(Serise의 경우 한 컬럼이므로 by옵션 설정 필요 없음)
- axis = 0 이면 컬럼명을 정렬 기준 변수로 지정(default)
- axis = 1 이면 인덱스명을 정렬 기준 변수로 지정
ShortPassing 능력치 컬럼 기준 오름차순 정렬
players.sort_values(by = 'ShortPassing', axis = 0).head()
ShortPassing | Dribbling | LongPassing | BallControl | |
---|---|---|---|---|
Name | ||||
Deng Xiaofei | 7.0 | 6.0 | 12.0 | 11.0 |
Zhang Chong | 7.0 | 16.0 | 9.0 | 22.0 |
Cheng Yuelei | 8.0 | 13.0 | 10.0 | 18.0 |
A. Donnarumma | 11.0 | 19.0 | 11.0 | 23.0 |
Gabri Prestão | 11.0 | 18.0 | 12.0 | 20.0 |
7.1.1.2 ascending 옵션
- True(Default) : 오른차순 정렬
- False : 내림차순 정렬,
ShortPassing 컬럼 기준 내림차순 정렬
players.sort_values(ascending = False,by = 'ShortPassing').head()
ShortPassing | Dribbling | LongPassing | BallControl | |
---|---|---|---|---|
Name | ||||
David Silva | 93.0 | 89.0 | 87.0 | 94.0 |
L. Modrić | 93.0 | 90.0 | 88.0 | 93.0 |
T. Kroos | 92.0 | 81.0 | 93.0 | 90.0 |
K. De Bruyne | 92.0 | 86.0 | 91.0 | 91.0 |
C. Eriksen | 91.0 | 84.0 | 88.0 | 91.0 |
7.1.1.3 na_position 옵션
- 'last'(Defualt) : 결측값(NaN)을 뒤로 정렬
- 'first' : 결측값(NaN)을 앞으로 정렬
ShortPassing 컬럼 기준 내림차순 정렬하면서 NaN을 처음에 배치
players.sort_values(ascending = False,by = 'ShortPassing', na_position='first').head()
ShortPassing | Dribbling | LongPassing | BallControl | |
---|---|---|---|---|
Name | ||||
J. McNulty | NaN | NaN | NaN | NaN |
J. Barrera | NaN | NaN | NaN | NaN |
J. Stead | NaN | NaN | NaN | NaN |
A. Semprini | NaN | NaN | NaN | NaN |
R. Bingham | NaN | NaN | NaN | NaN |
7.1.1.4 inplace 옵션
- False(Default) : 정렬된 내용을 단순 출력만함
- True : 정렬된 내용을 DataFrame에 저장
players DataFrame에 정렬된 데이터를 저장
players.sort_values(ascending = False,by = 'ShortPassing', inplace = True)
players.head()
ShortPassing | Dribbling | LongPassing | BallControl | |
---|---|---|---|---|
Name | ||||
David Silva | 93.0 | 89.0 | 87.0 | 94.0 |
L. Modrić | 93.0 | 90.0 | 88.0 | 93.0 |
T. Kroos | 92.0 | 81.0 | 93.0 | 90.0 |
K. De Bruyne | 92.0 | 86.0 | 91.0 | 91.0 |
C. Eriksen | 91.0 | 84.0 | 88.0 | 91.0 |
7.1.1.5 axis 옵션
- axis = 0 : 열방향으로 정렬(위에서 아래로)
- axis = 1 : 행방향으로 정렬(좌에서 우로)
Index 명의 David Silva 기준으로 행방향 정렬
players.sort_values(axis = 1, by = 'David Silva').head()
LongPassing | Dribbling | ShortPassing | BallControl | |
---|---|---|---|---|
Name | ||||
David Silva | 87.0 | 89.0 | 93.0 | 94.0 |
L. Modrić | 88.0 | 90.0 | 93.0 | 93.0 |
T. Kroos | 93.0 | 81.0 | 92.0 | 90.0 |
K. De Bruyne | 91.0 | 86.0 | 92.0 | 91.0 |
C. Eriksen | 88.0 | 84.0 | 91.0 | 91.0 |
7.1.2 sort_index() : 인덱스명 정렬
sort_index 함수의 옵션(sort_values 와 옵션이 거의 동일)
- axis = 0(Default) : index명을 정렬
- axis = 1 : 컬럼명을 정렬
A 부터 오름차순 정렬
players.sort_index().head()
ShortPassing | Dribbling | LongPassing | BallControl | |
---|---|---|---|---|
Name | ||||
A. Abang | 52.0 | 56.0 | 28.0 | 59.0 |
A. Abdellaoui | 53.0 | 39.0 | 45.0 | 47.0 |
A. Abdennour | 58.0 | 48.0 | 62.0 | 51.0 |
A. Abdi | 74.0 | 70.0 | 72.0 | 74.0 |
A. Abdu Jaber | 49.0 | 61.0 | 40.0 | 59.0 |
내림차순 정렬
players.sort_index(ascending = False).head()
ShortPassing | Dribbling | LongPassing | BallControl | |
---|---|---|---|---|
Name | ||||
Óscar Whalley | 32.0 | 16.0 | 30.0 | 18.0 |
Óscar Valentín | 68.0 | 58.0 | 63.0 | 68.0 |
Óscar Plano | 68.0 | 72.0 | 65.0 | 73.0 |
Óscar Pinchi | 65.0 | 69.0 | 63.0 | 70.0 |
Óscar Gil | 37.0 | 57.0 | 34.0 | 50.0 |
컬럼명 정렬
players.sort_index(axis = 1).head()
BallControl | Dribbling | LongPassing | ShortPassing | |
---|---|---|---|---|
Name | ||||
David Silva | 94.0 | 89.0 | 87.0 | 93.0 |
L. Modrić | 93.0 | 90.0 | 88.0 | 93.0 |
T. Kroos | 90.0 | 81.0 | 93.0 | 92.0 |
K. De Bruyne | 91.0 | 86.0 | 91.0 | 92.0 |
C. Eriksen | 91.0 | 84.0 | 88.0 | 91.0 |
7.2 DataFrame의 rank
rank 함수 (데이터의 순위를 측정) 옵션
- ascending : False 이면 숫자가 큰 것이 순위가 높음(rank 값이 작음)
- axis : 0이면 열방향, 1이면 행방향으로 순위 측정
- method : 동점인 경우 순위 측정에 사용할 방법(평균, 최소값, 최대값 등)
- pct : True 이면 상위 몇% 인지 보여줌
7.2.1 ascending 옵션
- True(Default) : 데이터 수치가 클 수록 rank값이 커짐(순위가 낮아짐)
- False : 데이터 수치가 작을 수록 rank값이 작아짐(순위가 높아짐)
컬럼별로 순위 측정(데이터 수치가 클수록 rank가 높음)
players.rank().head()
ShortPassing | Dribbling | LongPassing | BallControl | |
---|---|---|---|---|
Name | ||||
David Silva | 18158.5 | 18131.5 | 18145.0 | 18155.0 |
L. Modrić | 18158.5 | 18141.5 | 18150.5 | 18152.5 |
T. Kroos | 18156.5 | 17790.5 | 18159.0 | 18137.5 |
K. De Bruyne | 18156.5 | 18061.0 | 18158.0 | 18145.0 |
C. Eriksen | 18155.0 | 17982.5 | 18150.5 | 18145.0 |
players.rank(ascending = False).head()
ShortPassing | Dribbling | LongPassing | BallControl | |
---|---|---|---|---|
Name | ||||
David Silva | 1.5 | 28.5 | 15.0 | 5.0 |
L. Modrić | 1.5 | 18.5 | 9.5 | 7.5 |
T. Kroos | 3.5 | 369.5 | 1.0 | 22.5 |
K. De Bruyne | 3.5 | 99.0 | 2.0 | 15.0 |
C. Eriksen | 5.0 | 177.5 | 9.5 | 15.0 |
7.2.2 axis 옵션
- axis = 0(Defualt) : 열방향으로 순위 측정
- axis = 1 : 행방향으로 순위 측정
행방향으루 순위 측정(David Silva의 경우 BallControl 컬럼의 순위가 가장 높음)
players.rank(ascending = False, axis = 1).head()
ShortPassing | Dribbling | LongPassing | BallControl | |
---|---|---|---|---|
Name | ||||
David Silva | 2.0 | 3.0 | 4.0 | 1.0 |
L. Modrić | 1.5 | 3.0 | 4.0 | 1.5 |
T. Kroos | 2.0 | 4.0 | 1.0 | 3.0 |
K. De Bruyne | 1.0 | 4.0 | 2.5 | 2.5 |
C. Eriksen | 1.5 | 4.0 | 3.0 | 1.5 |
7.2.3 method 옵션
데이터 수치가 동점일 경우 순위 측정 방법
- average(Default) : 평균으로 순위 측정( Ex. 1위가 2명인경우 1.5 )
- first : 동점없이 정렬된 순서대로 순위 측정( Ex. 1위가 3명인 경위 위에서부터 1,2,3 )
- max : 동점인 데이터들 중 순위가 낮은 값 선정( Ex. 1위가 3명인 경우 3 )
- min : 동점인 데이터들 중 순위가 높은 값 선정( Ex. 1위가 3명인 경우 1등, 4번째 데이터의 경우 4등 )
- dense : min과 비슷하지만 동점 다음 데이터 순위 측정에서 차이가 있음( Ex. 1위가 3명인 경우 1등, 4번째 데이터의 경우 2등 )
순위가 동점이면 평균값 측정(David Silva와 L.Modric이 공동 1등이므로 1.5값 부여)
players.rank(ascending = False, method = 'average').head()
ShortPassing | Dribbling | LongPassing | BallControl | |
---|---|---|---|---|
Name | ||||
David Silva | 1.5 | 28.5 | 15.0 | 5.0 |
L. Modrić | 1.5 | 18.5 | 9.5 | 7.5 |
T. Kroos | 3.5 | 369.5 | 1.0 | 22.5 |
K. De Bruyne | 3.5 | 99.0 | 2.0 | 15.0 |
C. Eriksen | 5.0 | 177.5 | 9.5 | 15.0 |
players.rank(ascending = False, method = 'first').head()
ShortPassing | Dribbling | LongPassing | BallControl | |
---|---|---|---|---|
Name | ||||
David Silva | 1.0 | 25.0 | 11.0 | 4.0 |
L. Modrić | 2.0 | 13.0 | 9.0 | 7.0 |
T. Kroos | 3.0 | 332.0 | 1.0 | 18.0 |
K. De Bruyne | 4.0 | 80.0 | 2.0 | 13.0 |
C. Eriksen | 5.0 | 153.0 | 10.0 | 14.0 |
players.rank(ascending = False, method = 'max').head()
ShortPassing | Dribbling | LongPassing | BallControl | |
---|---|---|---|---|
Name | ||||
David Silva | 2.0 | 32.0 | 19.0 | 6.0 |
L. Modrić | 2.0 | 24.0 | 10.0 | 8.0 |
T. Kroos | 4.0 | 407.0 | 1.0 | 27.0 |
K. De Bruyne | 4.0 | 118.0 | 2.0 | 17.0 |
C. Eriksen | 5.0 | 202.0 | 10.0 | 17.0 |
players.rank(ascending = False, method = 'min').head()
ShortPassing | Dribbling | LongPassing | BallControl | |
---|---|---|---|---|
Name | ||||
David Silva | 1.0 | 25.0 | 11.0 | 4.0 |
L. Modrić | 1.0 | 13.0 | 9.0 | 7.0 |
T. Kroos | 3.0 | 332.0 | 1.0 | 18.0 |
K. De Bruyne | 3.0 | 80.0 | 2.0 | 13.0 |
C. Eriksen | 5.0 | 153.0 | 9.0 | 13.0 |
players.rank(ascending = False, method = 'dense').head()
ShortPassing | Dribbling | LongPassing | BallControl | |
---|---|---|---|---|
Name | ||||
David Silva | 1.0 | 9.0 | 6.0 | 3.0 |
L. Modrić | 1.0 | 8.0 | 5.0 | 4.0 |
T. Kroos | 2.0 | 17.0 | 1.0 | 7.0 |
K. De Bruyne | 2.0 | 12.0 | 2.0 | 6.0 |
C. Eriksen | 3.0 | 14.0 | 5.0 | 6.0 |
7.2.4 pct 옵션
- False(Default) : rank를 순위(숫자)로 매김
- True : 순위의 퍼센테이지값으로 매김(ex. 4명 중 1등인 경우 0.25, 4등은 1.0)
players 데이터 확인
players.head()
ShortPassing | Dribbling | LongPassing | BallControl | |
---|---|---|---|---|
Name | ||||
David Silva | 93.0 | 89.0 | 87.0 | 94.0 |
L. Modrić | 93.0 | 90.0 | 88.0 | 93.0 |
T. Kroos | 92.0 | 81.0 | 93.0 | 90.0 |
K. De Bruyne | 92.0 | 86.0 | 91.0 | 91.0 |
C. Eriksen | 91.0 | 84.0 | 88.0 | 91.0 |
행방향으로 퍼센테이지 순위 측정(David Silva의 경우 BallControl이 1등이므로 0.25)
players.rank(ascending = False, axis = 1, pct = True).head()
ShortPassing | Dribbling | LongPassing | BallControl | |
---|---|---|---|---|
Name | ||||
David Silva | 0.500 | 0.75 | 1.000 | 0.250 |
L. Modrić | 0.375 | 0.75 | 1.000 | 0.375 |
T. Kroos | 0.500 | 1.00 | 0.250 | 0.750 |
K. De Bruyne | 0.250 | 1.00 | 0.625 | 0.625 |
C. Eriksen | 0.375 | 1.00 | 0.750 | 0.375 |
위의 Jupyter notebook 내용은 여기 Github에서도 확인 할 수 있습니다.
감사합니다.
'데이터 분석 > Pandas' 카테고리의 다른 글
[Pandas 기초]10.DataFrame의 집계(그루핑) 함수 (1) | 2019.08.31 |
---|---|
[Pandas 기초]9.Series와 DataFrame에 함수 적용하기 (0) | 2019.08.29 |
[Pandas 기초]7.Pandas DataFrame 통계 (0) | 2019.08.27 |
[Pandas 기초]6.Pandas DataFrame 산술 연산 (2) | 2019.08.22 |
[Pandas 기초]5.Pandas 데이터 파일 입출력 (3) | 2019.08.20 |