본문 바로가기
Python/Pandas

숫자형 인덱스(Index)타입(Int64Index, Float64Index)-pandas(47)

by 콩돌 2021. 1. 4.
반응형

파이썬 버전 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 자료형과 유사하다.

 

※ 참고사항

정수기반의 인덱스에서 float을 사용하여 인덱싱 하는 것은 0.18.0부터 지원되기 시작했다. 

관련된 요약본은 여기(링크)를 참고할 수 있다.

 

정수축 레이블을 사용한 레이블 기반의 인덱싱은 골치아프며, 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

  

 

 

 

 

 

 

반응형

댓글