파이썬 버전 3.8 기준
pandas 버전 1.2.0 기준
숫자형 인덱스 유형 |
본 포스팅에서는 Pandas에서 제공하는 숫자형 인덱스 타입에 대해 다루도록 한다.
Int64Index, RangeIndex, Float64Index 대해 다뤄보도록 한다.
정수형 인덱스 타입 |
Int64Index 와 RangeIndex |
Int64Index는 정수를 기반으로 한 인덱스로, pandas에서 근본적인 기초인덱스이다.
이 인덱스는 정렬되고 슬라이스가 가능한 세트를 실행하는 불변형 배열이다.
0.18.0 버전 이전에는 NDFrame 객체에 대해 Int64Index가 기본인덱스로 제공되었다.
RangeIndex는 Int64Index의 서브클래스이며, 0.18.0 버전에서 추가되었다.
지금은 NDFrame에 기본값으로 제공되고 있다.
RangeIndex는 단조롭게 정렬된 데이터 셋에 최적화된 버전이다.
이는 파이썬의 range 자료형과 유사하다.
정수축 레이블을 사용한 레이블 기반의 인덱싱은 골치아프며, pandas 관련 커뮤니티에서 논란이 되고 있는 주제이다.
일단, pandas에서 일반적인 관점은 레이블이 정수위치보다 중요하다는 것이다.
그러므로 정수축 인덱스를 사용한 레이블 기반의 인덱싱은 .loc와 같은 일반적인 도구를 사용해서 가능하다.
정수 위치보다 .loc 메서드 사용시 레이블이 더 중요하기 때문에 없는 레이블을 사용시 예외가 발생한다.
○ 아래 예제에서 -1이라는 정수형 레이블은 없기 때문에 예외를 발생시킨다.
○ 레이블 기반의 인덱싱의 경우 슬라이싱을 사용할 경우, 슬라이싱 입력의 레이블이 없는 경우 입력된 인덱스의 위치를 예상하여 출력하는 경우가 존재한다.
정수형 인덱싱 예제)
# pandas와 numpy의 import
In[2]: import pandas as pd
In[3]: import numpy as np
In[4]: ex_df= pd.DataFrame(np.ones( [4, 4] ) )
# .loc 메서드 사용시 오류 예제
In[5]: ex_df.loc[-1]
KeyError: -1
# .loc 메서드를 통한 슬라이싱 예제
In[6]: ex_df.loc[-2 : ]
Out[6]:
0 1 2 3
0 1.0 1.0 1.0 1.0
1 1.0 1.0 1.0 1.0
2 1.0 1.0 1.0 1.0
3 1.0 1.0 1.0 1.0
[ ]를 이용한 인덱싱을 할 경우 인덱스를 인지하지 못할 경우 위치 기반으로 인덱싱을 수행하는 경우가 있으니 주의할 필요가 있다.
[ ]를 인덱싱 예제)
In[7]: ex_df[-2 : ]
Out[7]:
0 1 2 3
2 1.0 1.0 1.0 1.0
3 1.0 1.0 1.0 1.0
실수형 인덱스 타입 |
Float64Index |
Float64Index는 실수값(floating)을 기반으로한 인덱스이다.
정수와 floating값이 섞어 인덱스를 생성하면, 기본값으로 Float64Index가 자동으로 생성되어진다.
이를 통해 스칼라 인덱싱 및 슬라이싱에 대한 [ ], ix, loc을 정확히 동일하게 만드는 순수한 레이블 기반 슬라이싱 패러다임을 사용할 수 있다.
다음은 예제를 수행하기 위한 Series 생성을 보여준다.
Float64Index를 가지는 예제용 Series 생성)
# pandas와 numpy의 import
In[8]: index_float = pd.Index([1.0, 1.5, 2, 2.5, 3])
In[9]: index_float
Out[9]: Float64Index([1.0, 1.5, 2.0, 2.5, 3.0], dtype='float64')
In[10]: ex_s = pd.Series(np.arange(5), index=index_float)
In[11]: ex_s
Out[11]:
1.0 0
1.5 1
2.0 2
2.5 3
3.0 4
dtype: int32
[ ], .loc에 대한 스칼라 선택은 항상 레이블을 기반으로한다.
따라서 해당 위의 기능에 정수를 입력할 경우 같은 값을 출력한다.
[ ]와 .loc을 이용한 인덱싱 예제)
# [ ]를 이용한 인덱싱 예제
In[12]: ex_s[3]
Out[12]: 4
In[13]: ex_s[3.0]
Out[13]: 4
# .loc를 이용한 인덱싱 예제
In[14]: ex_s.loc[3]
Out[14]: 4
In[15]: ex_s.loc[3.0]
Out[15]: 4
위치기반은 인덱싱은 오직 .iloc만을 이용해서 가능하다.
.iloc 메서드를 이용한 인덱싱 예제)
In[16]: ex_s.iloc[4]
Out[16]: 4
인덱스에서 찾을 수 없는 스칼라 인덱스가 입력될 경우 KerError가 발생한다.
이 경우 슬라이싱을 사용할 경우 슬라이싱에 포함되는 값들을 구할 수 있다.
float 인덱스에서 float을 사용한 슬라이싱은 사용 가능하다.
단, 슬라이스가 불린인덱스인 경우는 예외적으로, 항상 위치가 지정된다.
실수형 인덱스 슬라이싱 사용 예제)
# .loc의 슬라이싱 사용 예제
In[17]: ex_s.loc[2.1:2.9]
Out[17]:
2.5 3
dtype: int32
In[20]: ex_s.loc[2:3]
Out[20]:
2.0 2
2.5 3
3.0 4
dtype: int32
# [ ] 의 슬라이싱 사용 예제
In[18]: ex_s[2.1:2.9]
Out[18]:
2.5 3
dtype: int32
In[19]: ex_s[2:3]
Out[19]:
2.0 2
2.5 3
3.0 4
dtype: int32
# .iloc 의 슬라이싱 사용 예제
In[21]: ex_s.iloc[2:3]
Out[21]:
2.0 2
dtype: int32
float 인덱스가 아닐때에는 float을 사용한 인덱싱 및 슬라이싱은 예외를 발생시키므로 주의하자.
실수 인덱스 사용 시 예제)
# 인덱싱 예제
In[22]: pd.Series(range(5))[2.5]
KeyError: 2.5
In[23]: pd.Series(range(5))[2]
Out[23]: 2
# 슬라이싱 예제
In[24]: pd.Series(range(5))[2.5: ]
TypeError: cannot do slice indexing on RangeIndex with these indexers [2.5] of type float
In[25]: pd.Series(range(5))[2: ]
Out[25]:
2 2
3 3
4 4
dtype: int64
※ 경고
.iloc에서 스칼라 float 인덱서를 사용하는 것은 0.18.0에서 삭제됬다.
따라서 아래와 같이 에러를 발생시킨다.
.iloc 에서 실수 인덱싱 사용 예)
In[26]: ex_s.iloc[1.5]
TypeError: Cannot index by location index with a non-integer key
실수인덱싱 실제 사용 예 |
다소 불규칙한 timedelta와 유사한 인덱싱 스킴을 가지고 있는 경우는 실수인덱싱을 사용하는 것이 유리하다.
예를들어 다음과 같이 생각해보자.
○ 특정 실험 데이터는 인덱스가 float으로 기록되어있다.
▷ 예를들어 millisecond에 따라 데이터가 출력된 경우가 존재한다.
실수 인덱싱 예제)
# 예제용 DataFrame의 생성
In[27]: ex_float = pd.DataFrame([np.random.randn(2), np.random.randn(2), np.random.randn(2), np.random.randn(2), np.random.randn(2) ], index=[0, 300.1, 599.8, 900.05, 1199.8], columns=('A', 'B') )
In[28]: ex_float
Out[28]:
A B
0.00 0.613574 -1.348004
300.10 -0.816054 -1.155008
599.80 0.073374 -0.916486
900.05 -0.441965 -1.965102
1199.80 -0.614322 0.636543
선택 연산은 모든 선택 연산자에 대해 항상 값을 기반으로 작동한다.
실수 인덱싱 예제)
# 데이터의 슬라이싱
In[29]: ex_float.loc[0:600]
Out[29]:
A B
0.0 0.613574 -1.348004
300.1 -0.816054 -1.155008
599.8 0.073374 -0.916486
In[30]: ex_float.loc[:600, 'B']
Out[30]:
0.0 -1.348004
300.1 -1.155008
599.8 -0.916486
Name: B, dtype: float64
필요에 따라 위치기반 인덱싱이 요구되는 경우, iloc를 사용하면 된다.
○ 이외에 만약 사용자가 정수기반의 선택이 필요하다면, 반드시 .iloc를 사용하자.
위치기반 인덱싱 사용 예제)
In[31]: ex_float.iloc[1:4]
Out[31]:
A B
300.10 -0.816054 -1.155008
599.80 0.073374 -0.916486
900.05 -0.441965 -1.965102
|
|
|
| 참고자료 https://pandas.pydata.org/pandas-docs/stable/user_guide/advanced.html
|
|
|
|
|
'Python > Pandas' 카테고리의 다른 글
카테고리 인덱스(CategoricalIndex) 기반 중복인덱싱-pandas(49) (4) | 2021.01.06 |
---|---|
구간 인덱스 타입(IntervalIndex)과 구간인덱스 생성-pandas(48) (0) | 2021.01.05 |
멀티인덱스와 인덱스 정렬, sort_index()메서드-pandas(46) (0) | 2020.12.29 |
데이터의 열의 빠른 추출, take() 메서드-pandas(45) (0) | 2020.12.28 |
멀티인덱스의 슬라이스(slice)와 단면(cross-section)추출-pandas(44) (0) | 2020.12.27 |
댓글