파이썬 버전 3.8 기준
pandas 버전 1.2.0 기준
카테고리 인덱스(CategoricalIndex)기반 중복인덱싱 |
본 포스팅에서는 Pandas에서 제공하는 카테고리 인덱스(CategoricalIndex) 타입에 대해 다루도록 한다.
CategoricalIndex |
CategoricalIndex는 카테고리 인덱스로 pandas에서 제공하는 인덱스 유형 중 하나이다.
이 인덱스는 카테고리로 나누어 값을 저장할 수 있는 인덱스를 형성시킬 수 있다.
○ 중복되는 인덱스에 여러가지 값을 담을 수 있으며 해당 인덱스는 카테고리로 인식된다.
○ 따라서 복사본(중복)을 사용한 인덱싱을 필요로 할 때 유용하다.
○ 효율적인 인덱싱과 많은 수의 중복된 요소를 포함하는 인덱스의 저장을 가능하게 한다.
CategoricalIndex 예제 |
다음은 예제수행을 위한 카테고리 인덱스를 가지는 DataFrame의 생성하는 예제이다.
모듈의 임폴트 및 카테고리 인덱스를 가지는 DataFrame의 생성)
# pandas와 numpy의 import
In[2]: import pandas as pd
In[3]: import numpy as np
In[4]: from pandas.api.types import CategoricalDtype
# DataFrame의 생성
In[5]: ex_df = pd.DataFrame({"A": np.arange(6), "B":list("cbaaba")})
In[6]: ex_df
Out[6]:
A B
0 0 c
1 1 b
2 2 a
3 3 a
4 4 b
5 5 a
In[7]: ex_df.dtypes
Out[7]:
A int32
B object
dtype: object
# 'B' 객체의 카테고리 인덱스 타입으로의 변경
In[8]: ex_df["B"] = ex_df["B"].astype(CategoricalDtype(list("cab")))
In[9]: ex_df
Out[9]:
A B
0 0 c
1 1 b
2 2 a
3 3 a
4 4 b
5 5 a
In[10]: ex_df.dtypes
Out[10]:
A int32
B category
dtype: object
In[11]: ex_df["B"].cat.categories
Out[11]: Index(['c', 'a', 'b'], dtype='object')
위의 예제에서 'B' 칼럼의 객체를 인덱스로 다음과 같이 세팅할 수 있다.
세팅을 완료하면 해당 객체의 인덱스는 CategoricalIndex이 된다.
index의 세팅)
# Index의 세팅
In[12]: ex_df2=ex_df.set_index('B')
# 세팅된 Index의 확인
In[13]: ex_df2.index
Out[13]: CategoricalIndex(['c', 'b', 'a', 'a', 'b', 'a'], categories=['c', 'a', 'b'], ordered=False, name='B', dtype='category')
In[14]: ex_df2
Out[14]:
A
B
c 0
b 1
a 2
a 3
b 4
a 5
__getiem__ / .iloc / .loc 메서드를 사용한 인덱싱은 복사본을 사용한 인덱스와 유사하게 작동한다.
인덱서는 반드시 카테고리 안에 있거나, 해당 연산은 KeyError를 일으킨다.
인덱싱 예제)
In[15]: ex_df2.loc['a']
Out[15]:
A
B
a 2
a 3
a 5
CategoricalIndex는 인덱싱 이후 보존된다.
인덱싱 이후의 카테고리 보존 예)
In[16]: ex_df2.loc['a'].index
Out[16]: CategoricalIndex(['a', 'a', 'a'], categories=['c', 'a', 'b'], ordered=False, name='B', dtype='category')
인덱싱을 정렬하는 것은 카테고리의 순서에 따라 정렬한다.
○ 예를들어 현재 수행 중인 예제를 기준으로는 카테고리 순서는 CategoricalDtype(list('cab'))을 사용한 인덱스를 다시 불러온다. 그래서 정렬된 순서는 cab이다.
카테고리 인덱스 정렬 예)
In[17]: ex_df2.sort_index()
Out[17]:
A
B
c 0
a 2
a 3
a 5
b 1
b 4
인덱스에서 Groupby 연산을 수행할 때 인덱스의 성질 또한 보존한다.
groupby 메서드 사용 예제)
In[18]: ex_df2.groupby(level=0).sum()
Out[18]:
A
B
c 0
a 10
b 5
In[19]: ex_df2.groupby(level=0).sum().index
Out[19]: CategoricalIndex(['c', 'a', 'b'], categories=['c', 'a', 'b'], ordered=False, name='B', dtype='category')
reindex() 메서드는 입력된 인덱서의 자료형에 기반하여 결과로 나오는 인덱스를 반환한다.
리스트를 입력하는 것은 평범한 인덱스를 반환하는 반면에,
Categorical 을 사용한 인덱싱은 CategoricalIndex를 반환한다.
○ 입력되는 Categorical dtype의 카테고리에 따라 인덱스되어진다.
이것은 심지어 카테고리에 없는 값을 사용한 임의의 인덱스를 할 수 있도록 한다.
○ 어떻게 다른 pandas 인덱스를 다시 인덱스 할 수 있을지와 유사하다.
reindex 메서드 사용 예제)
# 예제용 DataFrame의 생성
In[20]: ex_df3 = pd.DataFrame({"A": np.arange(3), "B": pd.Series(list("abc")).astype("category")})
# 일반적인 reindex 메서드 사용
In[21]: ex_df3.reindex(["a", "d"])
Out[21]:
A B
a NaN NaN
d NaN NaN
# ex1: 리스트를 사용한 reindex 메서드 사용 예제
In[22]: ex_df3=ex_df3.set_index("B")
In[23]: ex_df3.reindex(["a", "d"])
Out[23]:
A
B
a 0.0
d NaN
# ex1: 인덱스 타입 확인: 일반인덱스
In[24]: ex_df3.reindex(["a", "d"]).index
Out[24]: Index(['a', 'd'], dtype='object', name='B')
# ex2: 카테고리 인덱스를 사용한 reindex 메서드 사용 예제
In[25]: ex_df3.reindex(pd.Categorical(["a", "d"], categories=list("abd")))
Out[25]:
A
B
a 0.0
d NaN
# ex2: 인덱스 타입 확인: 일반인덱스
In[26]: ex_df3.reindex(pd.Categorical(["a", "e"], categories=list("abe"))).index
Out[26]: CategoricalIndex(['a', 'e'], categories=['a', 'b', 'e'], ordered=False, name='B', dtype='category')
※ 경고
CategoricalIndex에서의 재형성과 비교 연산은 반드시 같은 카테고리를 가져야하며, 그렇지 않으면, TypeError가 발생한다.
예제)
# 예제용 DataFrame 생성 1
In[27]: ex_df4 = pd.DataFrame({"A": np.arange(2), "B": list("ba")})
In[28]: ex_df4["B"] = ex_df4["B"].astype(CategoricalDtype(list("ab")))
In[29]: ex_df4 = ex_df4.set_index("B")
In[30]: ex_df4.index
Out[30]: CategoricalIndex(['b', 'a'], categories=['a', 'b'], ordered=False, name='B', dtype='category')
# 예제용 DataFrame 생성 2
In[31]: ex_df5 = pd.DataFrame({"A": np.arange(2), "B": list("bc")})
In[32]: ex_df5["B"] = ex_df5["B"].astype(CategoricalDtype(list("bc")))
In[33]: ex_df5 = ex_df5.set_index("B")
In[34]: ex_df5.index
Out[34]: CategoricalIndex(['b', 'c'], categories=['b', 'c'], ordered=False, name='B', dtype='category')
# 메서드 실패 예제
In[35]: pd.concat([ex_df4, ex_df5])
TypeError: categories must match existing categories when appending
|
|
|
| 참고자료 https://pandas.pydata.org/pandas-docs/stable/user_guide/advanced.html
|
|
|
|
|
'Python > Pandas' 카테고리의 다른 글
구간 인덱스 타입(IntervalIndex)과 구간인덱스 생성-pandas(48) (0) | 2021.01.05 |
---|---|
숫자형 인덱스(Index)타입(Int64Index, Float64Index)-pandas(47) (0) | 2021.01.04 |
멀티인덱스와 인덱스 정렬, sort_index()메서드-pandas(46) (0) | 2020.12.29 |
데이터의 열의 빠른 추출, take() 메서드-pandas(45) (0) | 2020.12.28 |
멀티인덱스의 슬라이스(slice)와 단면(cross-section)추출-pandas(44) (0) | 2020.12.27 |
댓글