파이썬 버전 3.8 기준
pandas 버전 1.2.0 기준
멀티인덱스(MultiIndex)와 인덱스 정렬 sort_index()메서드 |
본 포스팅에서는 멀티인덱스(MultiIndex)와 인덱스를 정렬하는 방법에 해대 다뤄보도록 한다.
이를 위해 sort_index() 메서드를를 사용하고, 해당 메서드에 대한 설명을 해보도록 한다.
추가적으로 is_lexsorted() 메서드를 이용한 인덱스가 정렬여부 확인 예제와 lexsort_depth 속성을 통해 멀티인덱스 정렬의 깊이를 확인할 수 있는 예제를 다루도록한다.
MultiIndex와 Index의 정렬 |
멀티인덱스(MultiIndex)와 인덱스(index)의 정렬을 위해 sort_index() 메서드를 사용할 수 있다.
sort_index() 메서드는 주어진 축을 따라 레이블을 이용하여 정렬을 수행한다.
○ 이는 슬라이스나 인덱싱을 더 효율적으로 가능하게 한다.
sort_index() 메서드의 사용 형식은 다음과 같다.
메서드 사용 형식)
result=object.sort_index(axis=0, level=None, ascending=True, inplace=False)
각 입력 객체별 설명은 다음과 같다.
○ object: 메서드가 적용되는 객체로 DataFrame, Series 등이 해당된다.
○ level: 정렬을 할 레벨(level)을 선택한다.
○ axis: 메서드를 적용할 축을 입력받는다.
▷ 0 or 'index': 행의 인덱스를 정렬한다.(기본값)
▷ 1 or 'columns': 열의 인덱스를 정렬한다.
○ ascending: 오름차순/내림차순 정렬 여부를 결정한다.
▷ True: 오름차순으로 정렬한다.(기본값)
▷ False: 내림차순으로 정렬한다.
○ inplace: 원본객체를 변경할지 결정한다.
▷ True: 원본 객체를 정렬된 상태로 변경한다.
▷ False: 원본 객체를 변경하지 않는다. (기본값)
MultiIndex의 정렬 예제 |
예제를 수행하기에 앞서 다음과 같이 모듈들을 import하고 예제용 Series를 정의하였다.
멀티인덱스가 아닌 일반 인덱스에는 level만 입력할 필요 없이 아래 예제들과 동일하게 적용하면되므로 인덱스에 대한 예제는 따로 수행하지 않는다.
모듈의 임폴트)
# pandas와 numpy의 import
In[2]: import numpy as np
In[3]: import pandas as pd
In[4]: import random
# 예제용 인덱스 입력 튜플 정의
In[5]: ex_tuple=[('A','a'), ('A','b'), ('B','a'), ('B','b'), ('C','a'), ('C','b'), ('D','a'), ('D','b')]
In[6]: random.shuffle(ex_tuple)
In[7]: ex_tuple
Out[7]:
[('A', 'a'), ('C', 'a'), ('A', 'b'), ('B', 'b'), ('B', 'a'), ('D', 'b'), ('D', 'a'), ('C', 'b')]
# 예제용 Series 정의
In[8]: ex_s = pd.Series([0,1,2,3,4,5,6,7], index=pd.MultiIndex.from_tuples(ex_tuple))
In[9]: ex_s
Out[9]:
A a 0
C a 1
A b 2
B b 3
a 4
D b 5
a 6
C b 7
dtype: int64
아래는 Series에 sort_index()를 적용한 예제를 보여준다.
메서드 적용 예제)
# sort_index() 메서드 적용 예제
In[10]: ex_s.sort_index()
Out[10]:
A a 0
b 2
B a 4
b 3
C a 1
b 7
D a 6
b 5
dtype: int64
# level 입력변수 사용 예제 1
In[11]: ex_s.sort_index(level=0)
Out[11]:
A a 0
b 2
B a 4
b 3
C a 1
b 7
D a 6
b 5
dtype: int64
# level 입력변수 사용 예제 2
In[12]: ex_s.sort_index(level=1)
Out[12]:
A a 0
B a 4
C a 1
D a 6
A b 2
B b 3
C b 7
D b 5
dtype: int64
만약 MultiIndex의 레벨에 이름이 있다면, 사용자는 또한 단계의 이름을 sort_index() 메서드에 입력할 수 있다.
level 변수에 이름(문자열) 사용 예제 )
# 각 Level의 이름입력
In[13]: ex_s.index.set_names(['one', 'two'], inplace=True)
# level 변수에 이름(문자열) 사용 예제 1
In[14]: ex_s.sort_index(level='one')
Out[14]:
one two
A a 0
b 2
B a 4
b 3
C a 1
b 7
D a 6
b 5
dtype: int64
# level 변수에 이름(문자열) 사용 예제 2
In[15]: ex_s.sort_index(level='two')
Out[15]:
one two
A a 0
B a 4
C a 1
D a 6
A b 2
B b 3
C b 7
D b 5
dtype: int64
DataFrame과 같은 더 높은 차원의 객체에서는, 각 축에 따라 그리고 레벨(level)에 따라 인덱스를 정렬할 수 있다.
DataFrame에서의 정렬 예제)
# 예제용 DataFrame의 정의
In[16]: ex_df=pd.DataFrame([range(x*8,x*8+8) for x in range(4)], index= ['b', 'd', 'c', 'a'], columns= pd.MultiIndex.from_tuples(ex_tuple))
In[17]: ex_df
Out[17]:
A C A B D C
a a b b a b a b
b 0 1 2 3 4 5 6 7
d 8 9 10 11 12 13 14 15
c 16 17 18 19 20 21 22 23
a 24 25 26 27 28 29 30 31
# axis 변수의 사용 예제 1
In[18]: ex_df.sort_index(axis=1)
Out[18]:
A B C D
a b a b a b a b
b 0 2 4 3 1 7 6 5
d 8 10 12 11 9 15 14 13
c 16 18 20 19 17 23 22 21
a 24 26 28 27 25 31 30 29
# axis 변수의 사용 예제 2
In[19]: ex_df.sort_index(axis=0)
Out[19]:
A C A B D C
a a b b a b a b
a 24 25 26 27 28 29 30 31
b 0 1 2 3 4 5 6 7
c 16 17 18 19 20 21 22 23
d 8 9 10 11 12 13 14 15
# axis 변수와 level변수의 동시 사용 예제 1
In[20]: ex_df.sort_index(level=0, axis=1)
Out[20]:
A B C D
a b a b a b a b
b 0 2 4 3 1 7 6 5
d 8 10 12 11 9 15 14 13
c 16 18 20 19 17 23 22 21
a 24 26 28 27 25 31 30 29
# axis 변수와 level변수의 동시 사용 예제 2
In[21]: ex_df.sort_index(level=1, axis=1)
Out[21]:
A B C D A B C D
a a a a b b b b
b 0 4 1 6 2 3 7 5
d 8 12 9 14 10 11 15 13
c 16 20 17 22 18 19 23 21
a 24 28 25 30 26 27 31 29
데이터가 정렬되지 않았을 경우에도 인덱싱은 작동한다.
그러나 비효율적이며 이때 경우에 따라선 PerformanceWarning 메세지를 출력한다.
이것은 view가 아닌 데이터의 복사본을 반환한다.
비정렬된 멀티인덱스에서의 인덱싱)
In[22]: ex_df.loc(axis=1)[('C','b')]
Out[22]:
b 7
d 15
c 23
a 31
Name: (C, b), dtype: int64
게다가 사용자는 완전히 정렬되지 않은 인덱스에 슬라이싱을 시도할 경우 다음과 같은 메세지를 출력한다.
비정렬된 멀티인덱스에서 슬라이싱)
In[23]: ex_df.loc(axis=1)[('A','b'):('C','b')]
pandas.errors.UnsortedIndexError: 'Key length (2) was greater than MultiIndex lexsort depth (0)'
정렬을 수행한 경우에는 슬라이싱이 제대로 작동한다.
정렬된 멀티인덱스에서의 슬라이싱)
# pandas와 numpy의 import
In[24]: ex_df.sort_index(axis=1).loc(axis=1)[('A','b'):('C','b')]
Out[24]:
A B C
b a b a b
b 2 4 3 1 7
d 10 12 11 9 15
c 18 20 19 17 23
a 26 28 27 25 31
MultiIndex에서 is_lexsorted() 메서드는 인덱스가 정렬여부를 알려준다.
그리고 lexsort_depth 속성은 정렬의 깊이를 반환한다.
is_lexsorted() 메서드 및 lexsort_depth 메서드 사용 예제)
# is_lexsorted() 메서드 사용 예제
In[25]: ex_df.columns.is_lexsorted()
Out[25]: False
In[26]: ex_df.sort_index(axis=1).columns.is_lexsorted()
Out[26]: True
# lexsort_depth 메서드 사용 예제
In[27]: ex_df.columns.lexsort_depth
Out[27]: 0
In[28]: ex_df.sort_index(axis=1).columns.lexsort_depth
Out[28]: 2
ascending 입력변수를 이용하여 오름차순 혹은 내림차순으로 정렬을 조정할 수 있다.
기본값은 True로 오름차순으로 정렬하며 False을 할 경우 내림차순으로 정렬한다.
ascending 입력변수 사용 예제)
In[29]: ex_df.sort_index(axis=1, ascending=False)
Out[29]:
D C B A
b a b a b a b a
b 5 6 7 1 3 4 2 0
d 13 14 15 9 11 12 10 8
c 21 22 23 17 19 20 18 16
a 29 30 31 25 27 28 26 24
inplace 입력변수를 사용하여 메서드가 적용될 때 원본객체를 변경이 적용되게 할 수 있다.
기본값은 False로 변경이 적용되지 않는다.
inplace 입력변수 사용 예제)
In[30]: ex_df.sort_index(axis=1, inplace=True)
In[31]: ex_df
Out[31]:
A B C D
a b a b a b a b
b 0 2 4 3 1 7 6 5
d 8 10 12 11 9 15 14 13
c 16 18 20 19 17 23 22 21
a 24 26 28 27 25 31 30 29
메서드 세부사항 |
DataFrame.sort_index(self, axis=0, level=None, ascending=True, inplace=False, kind='quicksort', na_position='last', sort_remaining=True, by=None) |
축을 따라서 레이블을 통해 객체를 정렬한다.
axis: {0, 1, 'index', 'columns'}
기본값은 0이다.
정렬하려하는 축을 명시한다.
0은 열(혹은 인덱스)을, 1은 열을 나타낸다.
level: int, level name, list of ints, list of label names
만약에 None이 아니라면 명시된 인덱스 단계에서 값들을 정렬한다.
ascending: bool
기본값은 True이다.
오름차순(True)으로 정렬할지, 내림차순(False)으로 정렬할지 결정한다.
inplace: bool
기본값은 False이다.
True일 경우, 원본 객체를 수정한다.
kind: {'quicksort', 'mergesort', 'heapsort'}
기본값은 'quicksort'이다.
정렬알고리즘을 선택한다.
자세한 내용은 ndarray.np.sort관련 설명을 참고하자.
megesort는 안정적인 알고리즘이다.
DataFrame에 대해서 이 옵션은 오직 하나의 열 혹은 레이블만 정렬할때 적용된다.
na_position: {'first', 'last'}
기본값은 'last'이다.
'first'일 경우 NaN 값들을 시작지점에 둔다.
'last'일 경우 NaN값들을 마지막 지점에 둔다.
MultiIndex에서는 사용될 수 없다.
sort_remaining: bool
기본값은 True이다.
True 및 단계 및 인덱스 별 정렬이 MultiIndex인 경우, 지정된 단계를 기준으로 정렬 한 후 다른 단계도 순서대로 정렬한다.
MultiIndex.is_lexsorted(self) |
만약 코드가 사전형식(알파벳 순)으로 정렬되어 있다면 True를 반환한다.
'Python > Pandas' 카테고리의 다른 글
구간 인덱스 타입(IntervalIndex)과 구간인덱스 생성-pandas(48) (0) | 2021.01.05 |
---|---|
숫자형 인덱스(Index)타입(Int64Index, Float64Index)-pandas(47) (0) | 2021.01.04 |
데이터의 열의 빠른 추출, take() 메서드-pandas(45) (0) | 2020.12.28 |
멀티인덱스의 슬라이스(slice)와 단면(cross-section)추출-pandas(44) (0) | 2020.12.27 |
멀티인덱스(MultiIndex)의 인덱싱(indexing)-pandas(43) (0) | 2020.11.08 |
댓글