Series
와 DataFrame
객체를 다루는 다양한 도구를 살펴본다.
pandas
라이브러리는 보통 pd
라는 별칭으로 사용된다.
import pandas as pd
import numpy as np
랜덤 시드, 어레이 내부에 사용되는 부동소수점 정확도, 도표 크기 지정 옵션 등은 이전과 동일하다.
np.random.seed(12345)
np.set_printoptions(precision=4, suppress=True)
import matplotlib.pyplot as plt
plt.rc('figure', figsize=(10, 6))
Series
와 DataFrame
을 표로 보여줄 때 사용되는 행의 수를 20으로 지정한다.
기본 값은 60이다.
PREVIOUS_MAX_ROWS = pd.options.display.max_rows # 원래 60이 기본.
pd.set_option("max_rows", 20)
obj = pd.Series([4.5, 7.2, -5.3, 3.6], index=['d', 'b', 'a', 'c'])
obj
d 4.5 b 7.2 a -5.3 c 3.6 dtype: float64
새로운 인덱스가 추가되면 NaN
이 사용된다.
obj2 = obj.reindex(['a', 'b', 'c', 'd', 'e'])
obj2
a -5.3 b 7.2 c 3.6 d 4.5 e NaN dtype: float64
지정되지 않은 인덱스는 무시된다.
obj2 = obj.reindex(['a', 'c', 'd', 'e'])
obj2
a -5.3 c 3.6 d 4.5 e NaN dtype: float64
method
키워드 인자¶리인덱싱 과정에서 결측치가 발생할 때 여러 방식으로 채울 수 있다.
method='fill'
키워드 인자는 결측치를 위쪽에 위치한 값으로 채운다.
주의사항: 인덱스가 오름 또는 내림 차순으로 정렬되어 있는 경우에만 가능하다.
obj3 = pd.Series(['blue', 'purple', 'yellow'], index=[0, 2, 5])
obj3
0 blue 2 purple 5 yellow dtype: object
obj3.reindex(range(6), method='ffill')
0 blue 1 blue 2 purple 3 purple 4 purple 5 yellow dtype: object
물론 위쪽에 위치한 값이 없으면 결측치가 된다.
obj3.reindex(range(-1, 6), method='ffill')
-1 NaN 0 blue 1 blue 2 purple 3 purple 4 purple 5 yellow dtype: object
아랫쪽에 있는 값으로 채울 수도 있다.
obj3.reindex(range(-1, 6), method='bfill')
-1 blue 0 blue 1 purple 2 purple 3 yellow 4 yellow 5 yellow dtype: object
아니면 가장 가까운 곳에 있는 값으로 채울 수도 있다. 1번 인덱스의 경우처럼 거리가 같으면 아랫쪽에서 택한다.
obj3.reindex(range(-1, 6), method='nearest')
-1 blue 0 blue 1 purple 2 purple 3 purple 4 yellow 5 yellow dtype: object
fill_value
키워드 인자¶리인덱싱 과정에서 발생하는 모든 결측치를 지정된 값으로 대체할 수 있다.
기본값은 NaN
이다.
obj3.reindex(range(-1, 6), fill_value='No Color')
-1 No Color 0 blue 1 No Color 2 purple 3 No Color 4 No Color 5 yellow dtype: object
리인덱싱은 항상 새로운 시리즈를 생성한다.
따라서 obj3
자체는 변하지 않는다.
obj3
0 blue 2 purple 5 yellow dtype: object
데이터프레임은 (행의) index
와 (열의) columns
속성에 대해
리인덱싱이 가능하며 작동법은 시리지의 인덱싱과 동일하다.
frame = pd.DataFrame(np.arange(9).reshape((3, 3)),
index=['a', 'c', 'd'],
columns=['Ohio', 'Texas', 'California'])
frame
Ohio | Texas | California | |
---|---|---|---|
a | 0 | 1 | 2 |
c | 3 | 4 | 5 |
d | 6 | 7 | 8 |
reindex()
메서드는 기본적으로 행의 index
에 대해 작동한다.
frame2 = frame.reindex(['a', 'b', 'c', 'd'])
frame2
Ohio | Texas | California | |
---|---|---|---|
a | 0.0 | 1.0 | 2.0 |
b | NaN | NaN | NaN |
c | 3.0 | 4.0 | 5.0 |
d | 6.0 | 7.0 | 8.0 |
열의 columns
에 대해서는 columns
키워드 인자를 활용한다.
states = ['Texas', 'Utah', 'California']
frame.reindex(columns=states)
Texas | Utah | California | |
---|---|---|---|
a | 1 | NaN | 2 |
c | 4 | NaN | 5 |
d | 7 | NaN | 8 |
reindex()
메서드와 함께 사용할 수 있는 키워드 인자가 더 있지만 여기서는 다루지 않는다.
drop()
메서드 (p. 201)¶특정 행 또는 열의 인덱스를 제외한 나머지로 이루어진 시리즈/데이터프레임을 구할 때 사용한다.
시리즈의 경우 인덱스를 한 개 또는 여러 개 지정하면 나머지로 이루어진 시리즈를 얻는다.
obj = pd.Series(np.arange(5.), index=['a', 'b', 'c', 'd', 'e'])
obj
a 0.0 b 1.0 c 2.0 d 3.0 e 4.0 dtype: float64
new_obj = obj.drop('c')
new_obj
a 0.0 b 1.0 d 3.0 e 4.0 dtype: float64
obj.drop(['d', 'c'])
a 0.0 b 1.0 e 4.0 dtype: float64
원래의 시리즈를 직접 건드리지는 않는다.
obj
a 0.0 b 1.0 c 2.0 d 3.0 e 4.0 dtype: float64
하지만 inplace=True
키워드 인자를 이용하여 원본을 수정할 수도 있다.
물론 사용에 매우 주의해야 한다.
obj.drop('c', inplace=True)
obj
a 0.0 b 1.0 d 3.0 e 4.0 dtype: float64
데이터프레임의 경우도 기본적으로 행의 인덱스를 기준으로 작동한다.
data = pd.DataFrame(np.arange(16).reshape((4, 4)),
index=['Ohio', 'Colorado', 'Utah', 'New York'],
columns=['one', 'two', 'three', 'four'])
data
one | two | three | four | |
---|---|---|---|---|
Ohio | 0 | 1 | 2 | 3 |
Colorado | 4 | 5 | 6 | 7 |
Utah | 8 | 9 | 10 | 11 |
New York | 12 | 13 | 14 | 15 |
data.drop(['Colorado', 'Ohio'])
one | two | three | four | |
---|---|---|---|---|
Utah | 8 | 9 | 10 | 11 |
New York | 12 | 13 | 14 | 15 |
열을 기준으로 작동하게 하려면 axis=1
로 지정한다.
data.drop('two', axis=1)
one | three | four | |
---|---|---|---|
Ohio | 0 | 2 | 3 |
Colorado | 4 | 6 | 7 |
Utah | 8 | 10 | 11 |
New York | 12 | 14 | 15 |
axis='columns'
로 지정해도 된다.
data.drop(['two', 'four'], axis='columns')
one | three | |
---|---|---|
Ohio | 0 | 2 |
Colorado | 4 | 6 |
Utah | 8 | 10 |
New York | 12 | 14 |
inplace=True
키워드 인자를 사용하면 이번에도 원본을 수정함에 주의하라.
data.drop('two', axis=1, inplace=True)
data
one | three | four | |
---|---|---|---|
Ohio | 0 | 2 | 3 |
Colorado | 4 | 6 | 7 |
Utah | 8 | 10 | 11 |
New York | 12 | 14 | 15 |
시리즈의 경우 1차원 넘파이 어레이와 거의 동일하게 작동한다. 다만 정수 대신에 지정된 인덱스를 사용할 때 조금 차이가 있다.
obj = pd.Series(np.arange(4.), index=['a', 'b', 'c', 'd'])
obj
a 0.0 b 1.0 c 2.0 d 3.0 dtype: float64
obj['b']
1.0
obj[1]
1.0
obj[2:4]
c 2.0 d 3.0 dtype: float64
여러 개의 인덱스를 리스트로 지정하여 인덱싱을 진행할 수 있다.
obj[['b', 'a', 'd']]
b 1.0 a 0.0 d 3.0 dtype: float64
obj[[1, 3]]
b 1.0 d 3.0 dtype: float64
필터링(부울 인덱싱)은 동일하게 작동한다.
obj < 2
a True b True c False d False dtype: bool
obj[obj < 2]
a 0.0 b 1.0 dtype: float64
정수가 아닌 다른 인덱스 이름, 즉 라벨을 이용하는 슬라이싱은 양쪽 구간의 끝을 모두 포함하는 점이 다르다.
obj['b':'c']
b 1.0 c 2.0 dtype: float64
obj['b':'c'] = 5
obj
a 0.0 b 5.0 c 5.0 d 3.0 dtype: float64
주의사항: 라벨 슬라이싱은 기본적으로 알파벳 순서를 따르며 시리즈에 사용된 순서와 상관 없다.
obj.reindex(['b', 'd', 'c', 'a'])
b 5.0 d 3.0 c 5.0 a 0.0 dtype: float64
obj['b':'d']
b 5.0 c 5.0 d 3.0 dtype: float64
2차원 넘파이 어레이와 거의 유사하게 작동한다.
data = pd.DataFrame(np.arange(16).reshape((4, 4)),
index=['Ohio', 'Colorado', 'Utah', 'New York'],
columns=['one', 'two', 'three', 'four'])
data
one | two | three | four | |
---|---|---|---|---|
Ohio | 0 | 1 | 2 | 3 |
Colorado | 4 | 5 | 6 | 7 |
Utah | 8 | 9 | 10 | 11 |
New York | 12 | 13 | 14 | 15 |
인덱싱인 기본적으로 열을 기준으로 진행된다.
data['two']
Ohio 1 Colorado 5 Utah 9 New York 13 Name: two, dtype: int32
data[['three', 'one']]
three | one | |
---|---|---|
Ohio | 2 | 0 |
Colorado | 6 | 4 |
Utah | 10 | 8 |
New York | 14 | 12 |
하지만 숫자 슬라이싱은 행을 기준으로 작동한다.
data[:2]
one | two | three | four | |
---|---|---|---|---|
Ohio | 0 | 1 | 2 | 3 |
Colorado | 4 | 5 | 6 | 7 |
필터링(부울 인덱싱) 또한 넘파이 2차원 어레이와 동일하게 작동한다.
mask1 = data['three'] > 5
mask1
Ohio False Colorado True Utah True New York True Name: three, dtype: bool
data[mask1]
one | two | three | four | |
---|---|---|---|---|
Colorado | 4 | 5 | 6 | 7 |
Utah | 8 | 9 | 10 | 11 |
New York | 12 | 13 | 14 | 15 |
필터링을 이용하여 특정 항목의 값을 업데이트할 수도 있다.
~mask1
은 mask1
의 부정을 나타낸다.data[~mask1] = 0
data
one | two | three | four | |
---|---|---|---|---|
Ohio | 0 | 0 | 0 | 0 |
Colorado | 4 | 5 | 6 | 7 |
Utah | 8 | 9 | 10 | 11 |
New York | 12 | 13 | 14 | 15 |
각각의 항목에 대한 필터링도 비슷하게 작동한다.
mask2 = data < 6
mask2
one | two | three | four | |
---|---|---|---|---|
Ohio | True | True | True | True |
Colorado | True | True | False | False |
Utah | False | False | False | False |
New York | False | False | False | False |
data[mask2] = 0
data
one | two | three | four | |
---|---|---|---|---|
Ohio | 0 | 0 | 0 | 0 |
Colorado | 0 | 0 | 6 | 7 |
Utah | 8 | 9 | 10 | 11 |
New York | 12 | 13 | 14 | 15 |
loc()
또는 iloc()
메서드를 이용한다.
loc()
메서드: 라벨을 이용할 경우iloc()
메서드: 정수 인덱스를 이용할 경우data.loc['Colorado']
one 0 two 0 three 6 four 7 Name: Colorado, dtype: int32
data.iloc[2]
one 8 two 9 three 10 four 11 Name: Utah, dtype: int32
행과 열에 대해 동시에 인덱싱/슬라이싱을 사용할 수 있으며 2차원 넘파이 어레이가 작동하는 방식과 비슷하다.
data.loc['Colorado', ['two', 'three']]
two 0 three 6 Name: Colorado, dtype: int32
data.iloc[2, [3, 0, 1]]
four 11 one 8 two 9 Name: Utah, dtype: int32
data.iloc[[1, 2], [3, 0, 1]]
four | one | two | |
---|---|---|---|
Colorado | 7 | 0 | 0 |
Utah | 11 | 8 | 9 |
data.loc[:'Colorado', 'two']
Ohio 0 Colorado 0 Name: two, dtype: int32
인덱싱/슬라이싱에 이은 필터링을 연달아 적용할 수도 있다.
data.iloc[:, :3][data.three > 5]
one | two | three | |
---|---|---|---|
Colorado | 0 | 0 | 6 |
Utah | 8 | 9 | 10 |
New York | 12 | 13 | 14 |
시리즈/데이터프레임의 사칙 연산은 기본적으로 아래 원칙을 따른다.
NaN
으로 처리.s1 = pd.Series([7.3, -2.5, 3.4, 1.5], index=['a', 'c', 'd', 'e'])
s1
a 7.3 c -2.5 d 3.4 e 1.5 dtype: float64
s2 = pd.Series([-2.1, 3.6, -1.5, 4, 3.1],
index=['a', 'c', 'e', 'f', 'g'])
s2
a -2.1 c 3.6 e -1.5 f 4.0 g 3.1 dtype: float64
s1 + s2
a 5.2 c 1.1 d NaN e 0.0 f NaN g NaN dtype: float64
df1 = pd.DataFrame(np.arange(9.).reshape((3, 3)),
columns=list('bcd'),
index=['Ohio', 'Texas', 'Colorado'])
df1
b | c | d | |
---|---|---|---|
Ohio | 0.0 | 1.0 | 2.0 |
Texas | 3.0 | 4.0 | 5.0 |
Colorado | 6.0 | 7.0 | 8.0 |
df2 = pd.DataFrame(np.arange(12.).reshape((4, 3)), columns=list('bde'),
index=['Utah', 'Ohio', 'Texas', 'Oregon'])
df2
b | d | e | |
---|---|---|---|
Utah | 0.0 | 1.0 | 2.0 |
Ohio | 3.0 | 4.0 | 5.0 |
Texas | 6.0 | 7.0 | 8.0 |
Oregon | 9.0 | 10.0 | 11.0 |
df1 + df2
b | c | d | e | |
---|---|---|---|---|
Colorado | NaN | NaN | NaN | NaN |
Ohio | 3.0 | NaN | 6.0 | NaN |
Oregon | NaN | NaN | NaN | NaN |
Texas | 9.0 | NaN | 12.0 | NaN |
Utah | NaN | NaN | NaN | NaN |
기본적으로 사용되는 산술 연산 기호에 해당하는 메서드가 존재한다. 아래는 가장 많이 사용되는 연산 메서드들이다.
메서드 | 설명 |
---|---|
add() |
덧셈(+ ) 계산 메서드 |
sub() |
뺄셈(- ) 계산 메서드 |
mul() |
곱셈(* ) 계산 메서드 |
div() |
나눗셈(/ ) 계산 메서드 |
floordiv() |
몫 (// ) 계산 메서드 |
pow() |
거듭제곱(** ) 메서드 |
공통 인덱스가 아니거나 결측치가 이미 존재하는 경우 기본적으로 결측치로 처리된다.
하지만 fill_value
키워드 인자를 이용하여 지정된 값으로 처리하게 만들 수도 있다.
다만, 연산 기호 대신에 해당 연산의 메서드를 활용해야 한다.
df1.add(df2, fill_value=0)
A | B | |
---|---|---|
0 | 1.0 | 3.0 |
1 | 2.0 | 4.0 |
넘파이에서 2차원 어레이와 1차원 어레이 사이에 브로드캐스팅이 가능한 경우, 즉, 차원을 맞출 수 있는 경우에 연산이 가능했다.
arr = np.arange(12.).reshape((3, 4))
arr
array([[ 0., 1., 2., 3.], [ 4., 5., 6., 7.], [ 8., 9., 10., 11.]])
arr[0]
array([0., 1., 2., 3.])
arr - arr[0]
array([[0., 0., 0., 0.], [4., 4., 4., 4.], [8., 8., 8., 8.]])
브로드캐스팅이 불가능하면 오류가 발생한다.
arr[:,1]
array([1., 5., 9.])
try:
arr + arr[:, 1]
except:
print("브로드캐스팅 불가능!")
브로드캐스팅 불가능!
물론 아래와 같이 브로드캐스팅이 가능하도록 모양을 변환한 다음엔 연산이 가능하다.
arr_1 = arr[:,1][:, np.newaxis]
arr_1
array([[1.], [5.], [9.]])
arr + arr_1
array([[ 1., 2., 3., 4.], [ 9., 10., 11., 12.], [17., 18., 19., 20.]])
데이터프레임과 시리즈 사이의 연산도 동일하게 작동한다. 다만, 행 또는 열에 대한 연산 여부를 확실하게 구분해주어야 한다.
frame = pd.DataFrame(np.arange(12.).reshape((4, 3)),
columns=list('bde'),
index=['Utah', 'Ohio', 'Texas', 'Oregon'])
frame
b | d | e | |
---|---|---|---|
Utah | 0.0 | 1.0 | 2.0 |
Ohio | 3.0 | 4.0 | 5.0 |
Texas | 6.0 | 7.0 | 8.0 |
Oregon | 9.0 | 10.0 | 11.0 |
series = frame.iloc[0]
series
b 0.0 d 1.0 e 2.0 Name: Utah, dtype: float64
브로드캐스팅은 기본족으로 행 단위로 이루어진다. 따라서 아래처럼 데이터프레임과 시리즈의 연산을 그냥 적용할 수 있다.
frame - series
b | d | e | |
---|---|---|---|
Utah | 0.0 | 0.0 | 0.0 |
Ohio | 3.0 | 3.0 | 3.0 |
Texas | 6.0 | 6.0 | 6.0 |
Oregon | 9.0 | 9.0 | 9.0 |
공통 인덱스가 존재하면 두 인자 모두에 대해 브로드캐스팅이 적용된다.
series2 = pd.Series(range(3), index=['b', 'e', 'f'])
series2
b 0 e 1 f 2 dtype: int64
frame + series2
b | d | e | f | |
---|---|---|---|---|
Utah | 0.0 | NaN | 3.0 | NaN |
Ohio | 3.0 | NaN | 6.0 | NaN |
Texas | 6.0 | NaN | 9.0 | NaN |
Oregon | 9.0 | NaN | 12.0 | NaN |
열 단위로 데이터프레임과 시리즈를 더하려면
해당 연산 메서드를 axis=0
키워드 인자와 함께 적용해야 한다.
series3 = frame['d']
series3
Utah 1.0 Ohio 4.0 Texas 7.0 Oregon 10.0 Name: d, dtype: float64
frame.sub(series3, axis=0)
b | d | e | |
---|---|---|---|
Utah | -1.0 | 0.0 | 1.0 |
Ohio | -1.0 | 0.0 | 1.0 |
Texas | -1.0 | 0.0 | 1.0 |
Oregon | -1.0 | 0.0 | 1.0 |
axis='index'
를 사용해도 된다.
frame.sub(series3, axis='index')
b | d | e | |
---|---|---|---|
Utah | -1.0 | 0.0 | 1.0 |
Ohio | -1.0 | 0.0 | 1.0 |
Texas | -1.0 | 0.0 | 1.0 |
Oregon | -1.0 | 0.0 | 1.0 |
유니버설 함수는 넘파이의 경우와 동일하게 작동한다.
frame = pd.DataFrame(np.random.randn(4, 3), columns=list('bde'),
index=['Utah', 'Ohio', 'Texas', 'Oregon'])
frame
b | d | e | |
---|---|---|---|
Utah | -0.204708 | 0.478943 | -0.519439 |
Ohio | -0.555730 | 1.965781 | 1.393406 |
Texas | 0.092908 | 0.281746 | 0.769023 |
Oregon | 1.246435 | 1.007189 | -1.296221 |
넘파이의 abs()
함수를 적용하면 항목별로 이루어진다.
np.abs(frame)
b | d | e | |
---|---|---|---|
Utah | 0.204708 | 0.478943 | 0.519439 |
Ohio | 0.555730 | 1.965781 | 1.393406 |
Texas | 0.092908 | 0.281746 | 0.769023 |
Oregon | 1.246435 | 1.007189 | 1.296221 |
시리즈에 대해서도 동일하다.
np.abs(frame['b'])
Utah 0.204708 Ohio 0.555730 Texas 0.092908 Oregon 1.246435 Name: b, dtype: float64
map()
과 applymap()
메서드¶유니버설 함수가 아닌 함수를 시리즈의 항목별로 적용하려면
map()
메서드를 이용한다.
예를 들어 아래 람다(lambda) 함수는 부동소수점을 소수점 이하 셋째 자리에서 반올림한 값만 보여주도록 한다.
format = lambda x: '%.2f' % x
시리즈에 적용해보자.
frame['e'].map(format)
Utah -0.52 Ohio 1.39 Texas 0.77 Oregon -1.30 Name: e, dtype: object
유니버설 함수가 아닌 함수를 데이터프레임의 항목별로 적용하려면
applymap()
메서드를 이용한다.
frame.applymap(format)
b | d | e | |
---|---|---|---|
Utah | -0.20 | 0.48 | -0.52 |
Ohio | -0.56 | 1.97 | 1.39 |
Texas | 0.09 | 0.28 | 0.77 |
Oregon | 1.25 | 1.01 | -1.30 |
apply()
메서드¶행 또는 열 단위로 함수를 적용하려면 apply()
메서드를 활용한다.
기본은 열 단위로 함수가 적용되며 반환값이 스칼라 값이면 시리즈가 반환된다.
예를 들어 아래 함수는 최댓값과 최소값의 차이를 반환한다.
f1 = lambda x: x.max() - x.min()
데이터프레임에 적용하면 열 별로 최댓값과 최솟값의 차이를 계산하여 시리즈로 반환한다.
frame.apply(f1)
b 1.802165 d 1.684034 e 2.689627 dtype: float64
행 별로 함수를 적용하려면 axis=1
또는 axis='columls'
를 지정해야 한다.
frame.apply(f1, axis='columns')
Utah 0.998382 Ohio 2.521511 Texas 0.676115 Oregon 2.542656 dtype: float64
frame.apply(f1, axis=1)
Utah 0.998382 Ohio 2.521511 Texas 0.676115 Oregon 2.542656 dtype: float64
함수의 반환값이 시리즈이면 apply()
메서드는 데이터프레임을 반환된다.
예를 들어 아래 함수는 최솟값과 최댓값을 갖는 시리즈를 반환한다.
def f2(x):
return pd.Series([x.min(), x.max()], index=['min', 'max'])
apply()
메서드와 함께 호출하면 열 별로 최댓값과 최솟값을 계산하여 데이터프레임으로 반환한다.
frame.apply(f2)
b | d | e | |
---|---|---|---|
min | -0.555730 | 0.281746 | -1.296221 |
max | 1.246435 | 1.965781 | 1.393406 |
참고: 시리즈 객체 또한 apply()
메서드를 갖는다. 하지만
기본적으로 map()
메서드처럼 작동한다.
map()
메서드보다 좀 더 다야한 기능을 갖지만 여기서는 다루지 않는다.
행과 열의 인덱스 또는 항목을 대상으로 정렬할 수 있다.
sort_index()
메서드¶시리즈의 경우 인덱스를 기준으로 정렬한다.
obj = pd.Series(range(4), index=['d', 'a', 'b', 'c'])
obj
d 0 a 1 b 2 c 3 dtype: int64
obj.sort_index()
a 1 b 2 c 3 d 0 dtype: int64
내림차순으로 정렬하려면 ascending=False
키워드 인자를 함께 사용한다.
obj.sort_index(ascending=False)
d 0 c 3 b 2 a 1 dtype: int64
데이터프레임의 경우 행 또는 열의 인덱스를 기준으로 정렬한다.
frame = pd.DataFrame(np.arange(8).reshape((2, 4)),
index=['three', 'one'],
columns=['d', 'a', 'b', 'c'])
frame
d | a | b | c | |
---|---|---|---|---|
three | 0 | 1 | 2 | 3 |
one | 4 | 5 | 6 | 7 |
기본은 행의 인데스를 기준으로 정렬한다.
frame.sort_index()
d | a | b | c | |
---|---|---|---|---|
one | 4 | 5 | 6 | 7 |
three | 0 | 1 | 2 | 3 |
열의 인덱스를 기준으로 정렬하려면 axis=1
또는 axis='columns'
키워드 인자를 사용한다.
frame.sort_index(axis=1)
a | b | c | d | |
---|---|---|---|---|
three | 1 | 2 | 3 | 0 |
one | 5 | 6 | 7 | 4 |
frame.sort_index(axis='columns')
a | b | c | d | |
---|---|---|---|---|
three | 1 | 2 | 3 | 0 |
one | 5 | 6 | 7 | 4 |
내림차순으로 정렬하려면 ascending=False
키워드 인자를 함께 사용한다.
frame.sort_index(axis=1, ascending=False)
d | c | b | a | |
---|---|---|---|---|
three | 0 | 3 | 2 | 1 |
one | 4 | 7 | 6 | 5 |
sort_values()
메서드¶지정된 열 또는 행에 속한 값들을 기준으로 정렬할 때 사용한다.
obj = pd.Series([4, 7, -3, 2])
obj
0 4 1 7 2 -3 3 2 dtype: int64
obj.sort_values()
2 -3 3 2 0 4 1 7 dtype: int64
결측치는 맨 나중에 위치시킨다.
obj = pd.Series([4, np.nan, 7, np.nan, -3, 2])
obj
0 4.0 1 NaN 2 7.0 3 NaN 4 -3.0 5 2.0 dtype: float64
obj.sort_values()
4 -3.0 5 2.0 0 4.0 2 7.0 1 NaN 3 NaN dtype: float64
데이터프레임의 경우 by
키워드 인자를 이용하여 열의 라벨을 지정해야 한다.
frame = pd.DataFrame({'b': [4, 7, -3, 2], 'a': [0, 1, 0, 1]})
frame
b | a | |
---|---|---|
0 | 4 | 0 |
1 | 7 | 1 |
2 | -3 | 0 |
3 | 2 | 1 |
예를 들어 b
열의 값을 기준으로 정렬한다.
물론 동일한 행의 값은 함께 움직인다.
frame.sort_values(by='b')
b | a | |
---|---|---|
2 | -3 | 0 |
3 | 2 | 1 |
0 | 4 | 0 |
1 | 7 | 1 |
여러 열의 값을 기준으로 정렬하려면 라벨의 리스트를 입력한다. 그러면 리스트 항목 순서대로 기준이 정해진다.
예를 들어 아래 코드는 먼저 a
열의 항목들을 순서대로 정렬한 다음에
동등한 값의 경우에는 b
열의 항목들 순서대로 정렬한다.
frame.sort_values(by=['a', 'b'])
b | a | |
---|---|---|
2 | -3 | 0 |
0 | 4 | 0 |
3 | 2 | 1 |
1 | 7 | 1 |
참고: axis=1
을 이용하여 특정 행의 값을 기준으로 정렬할 수도 있다.
하지만 데이터프레임은 서로 다른 특성을 열 단위로 담는 목적으로
사용되기에 이런 정렬은 사용할 이유가 별로 없다.
frame.sort_values(by=2, axis=1, ascending=False)
a | b | |
---|---|---|
0 | 0 | 4 |
1 | 1 | 7 |
2 | 0 | -3 |
3 | 1 | 2 |