별의 공부 블로그 🧑🏻‍💻
728x90
728x170

데이터 처리

  • 판다스 객체에서 데이터 세트를 서브세트로 설정하거나 서브세트를 얻으려면 축을 라벨 처리해야 한다.
    • 라벨 처리는 데이터 분석, 시각화, 양방향 디스플레이 기능에서 중요한 과정이며, 데이터를 자동 정렬하고 명시적으로 표현한다.

 

데이터 선택

  • 데이터는 라벨(Label), 위치(Position), 호출(Call)을 이용해 선택할 수 있다.

 

① 라벨로 데이터 선택

  • 라벨을 이용한 데이터 선택은 임의의 축을 따라서 범위를 나누는 일관성 있는 방법으로써 loc 속성을 사용한다.
    • loc 속성에 입력할 수 있는 것들
      • 1 또는 a 와 같은 단일 라벨
      • ['a', 'b', 'c'] 와 같은 리스트나 라벨들의 배열
      • a:f 와 같은 슬라이스 객체
      • 불리언 배열
      • 호출 함수
  • loc 속성은 데이터의 인덱스 타입이 일치하지 않으면 오류가 발생하므로 인덱스 타입을 일치시켜야 한다.
df1 = pd.DataFrame(np.random.randn(5, 4), columns=list('ABCD'), index=pd.date_range('20210701', periods=5))
df1

 

df1.loc['20210702':'20210703']

 

df1.loc[2:3]    # 오류 발생
더보기
TypeError: cannot do slice indexing on DatetimeIndex with these indexers [2] of type int

 

  • 인덱스를 이용해 라벨을 선택하려면 모든 라벨이 인덱스에 포함되어야 하며, 그렇지 않으면 오류가 발생한다.
  • 슬라이싱할 때 시작과 끝의 범위는 포함된다.
>>> ser1 = pd.Series(np.random.randn(4), index=list('abcd'))
>>> ser1
a   -1.147430
b    0.058865
c   -0.506377
d    0.018776
dtype: float64

>>> ser1.loc['c':]
c   -0.506377
d    0.018776
dtype: float64

>>> ser1.loc['b']
0.05886489235705901

 

  • loc 속성을 사용해 시리즈 객체에 동적 할당을 할 수 있다.
>>> ser1.loc['c':] = 0
>>> ser1
a   -1.147430
b    0.058865
c    0.000000
d    0.000000
dtype: float64

 

  • 라벨을 이용해 데이터프레임의 요소를 선택할 수 있다.
df1 = pd.DataFrame(np.random.randn(5, 4), index=list('abcde'), columns=list('ABCD'))
df1

 

df1.loc[['a', 'b', 'd'], :]
더보기

 

  • df1.loc[['a', 'b', 'd'], :] df1.loc[['a', 'b', 'd']] 를 입력한 후의 결과는 같다.

 

  • 하나의 라벨과 슬라이싱을 이용해 데이터를 선택한다.
df1.loc['c':, 'A':'C']

 

>>> df1.loc['a']
A   -1.563361
B    0.028897
C   -0.919418
D   -0.585012
Name: a, dtype: float64

 

  • loc 속성을 이용해 슬라이싱을 실행할 때, 시작과 끝 라벨이 인덱스에 있다면 문자열로 인식해서 시작과 끝을 포함해 둘 사이에 위치하는 요소를 반환한다.
  • 인덱스를 수치로 간주한다면 속성 iloc을 적용한다.
>>> ser = pd.Series(list('abcde'), index=[0, 3, 2, 5, 4])
>>> ser
0    a
3    b
2    c
5    d
4    e
dtype: object4

>>> ser.loc[3:5]
3    b
2    c
5    d
dtype: object

 

  • ser.loc[1:6] 을 적용하면 2개의 라벨 요소 중 6이 인덱스 범위를 초과해 존재하지 않으므로 오류가 발생한다.
    • 그러나 인덱스 라벨을 순서 정렬한 후, loc[1:6]를 적용하면 범위에 맞는 결과가 나타난다.
      • 여기서 loc의 2개 라벨은 위치를 나타내는 것이 아니라 라벨 명칭인 점에 주의한다.
>>> ser.sort_index()
0    a
2    c
3    b
4    e
5    d
dtype: object

>>> ser.sort_index().loc[1:6]
3    b
4    e
5    d
dtype: object

 

② 위치로 데이터 선택

  • 위치를 이용해 데이터를 선택할 때, 슬라이싱 영역의 시작은 포함되고 끝은 제외된다.
  • iloc 속성으로 위치를 지정할 수 있으며, 정수, 리스트, 정수 배열을 입력으로 사용한다.
    • 정수 1:5와 같은 슬라이스 객체, 불리언 배열 그리고 호출 함수를 입력할 수 있다.
>>> ser1 = pd.Series(np.random.randn(5), index=list(range(0, 10, 2)))
>>> ser1
0   -0.221171
2   -0.935806
4   -0.529686
6   -2.150953
8    0.303440
dtype: float64

>>> ser1.iloc[:3]
0   -0.221171
2   -0.935806
4   -0.529686
dtype: float64

>>> ser1.iloc[3]
-2.1509533662669043

 

  • 데이터프레임 객체를 생성하고, 위치를 이용해 선택할 수 있다.
df1 = pd.DataFrame( np.random.randn(5, 4), index=list(range(0, 10, 2)), columns=list(range(0, 8, 2)))
df1

 

  • 정수를 범위로 가지는 슬라이싱을 이용해 데이터를 선택한다.
  • [n:m]은 위치 n부터 m-1까지의 범위이다.
df1.iloc[:2]

 

df1.iloc[1:3, 0:3]

 

  • 정수 리스트를 이용해 데이터를 선택한다.
df1.iloc[[0, 2, 3], [1, 3]]

 

  • df1 객체를 횡단으로 슬라이싱한다.
>>> df1.iloc[1]
0    0.087331
2    0.190744
4    0.487980
6   -0.596437
Name: 2, dtype: float64

 

③ 호출 함수로 데이터 선택

  • 호출 함수(Callable)호출할 수 있는 함수를 의미하며, loc, iloc [ ]를 이용해 인덱싱할 때 호출 함수를 인수인 인덱스 연산자로 사용할 수 있다.
  • 시리즈나 데이터프레임에서 호출 함수는 하나의 인수를 가지며, 인덱싱에 합당한 출력을 반환한다.
df1 = pd.DataFrame(np.random.randn(5, 4), index=list('abcde'), columns=list('ABCD'))
df1

 

  • 호출 함수를 인덱스 연산자로 사용하여 데이터를 선택해본다.
  • df1.A 가 0보다 큰 라벨 a와 b를 행 축으로 선택하고, [:]인 모든 구간을 열 축으로 선택한다.
df1.loc[lambda df: df.A>0, :]

 

  • 모든 행 구간을 선택하고 A와 B열을 선택한다.
df1.loc[:, lambda df: ['A', 'B']]

 

  • 위치를 이용해 데이터를 선택하기 위해 iloc 속성을 사용할 수 있다.
df1.iloc[:, lambda df: [0, 1]]

 

  • columns 속성을 이용해 열을 선택할 수 있다.
>>> df1[lambda df: df.columns[0]]
a   -0.964580
b    0.786939
c    0.351728
d    2.155382
e    0.338592
Name: A, dtype: float64

 

  • 시리즈에도 호출 함수 인덱스를 사용할 수 있다.
>>> df1.A.loc[lambda ser: ser > 0]
b    0.786939
c    0.351728
d    2.155382
e    0.338592
Name: A, dtype: float64

 

 

데이터 설정과 검색

  • 다양한 방법으로 데이터를 설정 또는 변형하고, 필요한 데이터를 검색할 수 있다.

 

데이터 확장 및 변경

  • 판다스의 데이터프레임이나 시리즈에 라벨을 지정하거나 슬라이싱을 실행하거나 loc, at, iat 메소드를 이용해 값을 할당하여 데이터를 확장하고 변경할 수 있다.
>>> ser = pd.Series(np.arange(3))
>>> ser
0    0
1    1
2    2
dtype: int32

>>> ser[5] = 7
>>> ser
0    0
1    1
2    2
5    7
dtype: int64

 

  • loc에 적용하면 데이터프레임을 확장할 수 있다.
df = pd.DataFrame(np.arange(9).reshape(3, 3), columns=['A', 'B', 'C'])
df

 

  • 전체 행과 A열을 선택한 요소를 전체 행과 D열의 범위에 할당한다.
df.loc[:, 'D'] = df.loc[:, 'A']
df

 

  • loc 를 이용하면 인덱스 라벨을 추가하고 새로운 값을 동적 할당할 수 있다.
df.loc[3] = 7
df

 

  • 모든 데이터 구조에서 사용할 수 있는 atiat 메소드를 사용하면 스칼라 값에 접근할 수 있다.
    • at loc 와 유사하게 라벨 기반의 스칼라에 접근한다.
    • iatiloc 와 유사하게 정수 기반 값에 접근한다.
>>> ser.iat[3]
'd'

>>> ser.at[5]
'd'

 

df.at[3, 'E'] = 7
df.iat[3, 0] = 2
df

 

불리언 벡터로 데이터 필터링

  • 데이터를 필터링할 때 불리언 벡터를 사용하는 연산을 주로 활용한다.
  • 연산자 or |, and&, not~로 사용한다.
>>> ser = pd.Series(range(-3, 3))
>>> ser
0   -3
1   -2
2   -1
3    0
4    1
5    2
dtype: int64

>>> ser[ser > 0]
4    1
5    2
dtype: int64

>>> ser[(ser < -1) | (ser > 1)]
0   -3
1   -2
5    2
dtype: int64

>>> ser[~(ser < 2)]
5    2
dtype: int64

 

  • 불리언 벡터에 조건을 부여해 데이터프레임에서 행을 선택할 수 있다.
df[df['A'] < 3]

 

  • isin() 메소드는 시리즈 전체에서 선택된 범위 요소 중, isin() 메소드인수로 전달된 요소가 존재하면 True, 그렇지 않으면 False를 반환한다.
  • ser[::-1] 은 인덱스 라벨을 역으로 나타낸다.
>>> ser[::-1].isin([-3, -1, 2])
5     True
4    False
3    False
2     True
1    False
0     True
dtype: bool

>>> ser[ser[::-1].isin([-3, -1, 2])]
0   -3
2   -1
5    2
dtype: int64

 

  • index 객체에도 isin() 메소드를 적용할 수 있으며, 이 메소드는 찾는 라벨이 존재하는지 알 수 없는 경우에 유용하다.
>>> ser.index.isin([2, 4, 6])
array([False, False,  True, False,  True, False])

>>> ser[ser.index.isin([2, 4, 6])]
2   -1
4    1
dtype: int64

 

  • 데이터프레임에도 isin() 메소드를 사용할 수 있다.
    • isin() 메소드 호출 시, 배열이나 딕셔너리 중 하나의 형태로 값들의 세트를 전달한다.
    • 값이 배열이면 isin()은 원래 데이터프레임과 같은 shape인 불리언 데이터프레임을 반환한다.
df = pd.DataFrame({'no': [1, 2, 3], 'ha': ['a', 'b', 'c'], 'hi': ['m', 'n', 'o']})
val = ['a', 'n', 1, 3]
df

 

df.isin(val)

 

  • 특정 열에서 값을 선택할 수도 있다.
val = {'ha': ['a', 'c'], 'no': [1, 2]}
df.isin(val)

 

  • 데이터의 서브세트를 빠르게 선택하기 위해 데이터프레임의 isin() 메소드any(), all() 메소드와 조합해 사용할 수 있다.
val = {'ha': ['a', 'c'], 'hi': ['m', 'o'], 'no': [1, 2]}
mask = df.isin(val).all(1)
df[mask]

 

take() 메소드로 검색

  • 판다스의 인덱스, 시리즈데이터프레임은 인덱스에서 축에 따른 요소를 검색하는 take() 메소드를 제공한다.
    • 이때 인덱스는 리스트 혹은 정수 인덱스 위치의 ndarray 이어야 한다.
>>> index = pd.Index(np.random.randint(0, 1000, 6))
>>> index
Int64Index([702, 485, 470, 493, 220, 442], dtype='int64')

>>> positions = [0, 2, 5]
>>> index[positions]
Int64Index([702, 470, 442], dtype='int64')

>>> index.take(positions)
Int64Index([702, 470, 442], dtype='int64')

>>> ser = pd.Series(np.random.randn(10))
>>> ser.iloc[positions]
0   -1.800911
2    1.351300
5    1.461708
dtype: float64

>>> ser.take(positions)
0   -1.800911
2    1.351300
5    1.461708
dtype: float64

 

df = pd.DataFrame(np.random.randn(5, 3))
df.take([1, 4, 3])

 

df.take([0, 2], axis=1)

 

 

손실 데이터 처리

  • 판다스를 통해 손실 데이터를 매우 유연하게 처리할 수 있다.
d = {'one': [1.5, 2.2, -3.0], 'two': [1.0, -1.2, 5.0], 'three': [-1.1, 2.0, 4.0]}
df = pd.DataFrame(d, index = ['a', 'c', 'f'])
df['four'] = 'ha'
df['five'] = df['one'] > 0
df

 

  • reindex() 메소드를 사용하여 존재하지 않는 요솟값 NaN을 갖도록 df에 새로운 인덱스를 추가하였다.
df1 = df.reindex(['a', 'b', 'c', 'd', 'e', 'f'])
df1

 

  • 판다스는 손실 값을 쉽게 탐지할 수 있도록 시리즈와 데이터프레임의 isna() notna() 메소드를 제공한다.
>>> df1['one']
a    1.5
b    NaN
c    2.2
d    NaN
e    NaN
f   -3.0
Name: one, dtype: float64

>>> pd.isna(df1['one'])
a    False
b     True
c    False
d     True
e     True
f    False
Name: one, dtype: bool

>>> df1['four'].notna()
a     True
b    False
c     True
d    False
e    False
f     True
Name: four, dtype: bool

 

  • 파이썬NoneNone은 서로 같지만, 넘파이nannan은 서로 다르다는 점에 주의한다.
>>> None == None
True

>>> np.nan == np.nan
False

 

손실 데이터 계산

  • 판다스 객체들을 산술 연산할 때 손실 값들은 브로드캐스팅되어 연산된다.
d1 = {'one': [1.0, 2.0, 3.0], 'two': [4.0, 5.0, 6.0]}
df1 = pd.DataFrame(d1, index = ['a', 'b', 'c'])
df2 = df1.copy()
df2.loc['d'] = np.nan
df2['three'] = 2.0
df2.iloc[1:2, 1:2] = np.nan
df1

 

df2

 

df1 + df2

 

  • 값이 비어 있거나 모두 NA인 시리즈의 합은 0이고, 곱은 1이다.
>>> pd.Series([np.nan]).sum()
0.0

>>> pd.Series([], dtype=object).sum()
0

>>> pd.Series([np.nan]).prod()
1.0

>>> pd.Series([], dtype=object).prod()
1

 

  • GroupBy 에서 NA는 자동으로 제외된다.
df2

 

df2.groupby('two').mean()

 

손실 데이터 채우기

  • 판다스는 손실 데이터를 처리하는 다양한 방법을 제공한다.
  • fillna() 메소드를 이용해 NA를 스칼라 값으로 대체할 수 있다.
df2.fillna(0)

 

>>> df2['one'].fillna('missing')
a          1
b          2
c          3
d    missing
Name: one, dtype: object

 

  • method='pad'를 이용해 손실 값을 앞 데이터의 값으로 채울 수 있다.
df2

 

df2.fillna(method='pad')

 

  • fillna() 메소드에 판다스 객체를 인수로 입력해 손실 값을 채울 수 있다.
  • 딕셔너리의 라벨이나 시리즈의 인덱스는 채우고자 하는 프레임의 에 맞춰야 한다.
df2.loc['c', 'three'] = np.nan
df2

 

>>> df2.mean()
one      2.0
two      5.0
three    2.0
dtype: float64

 

df2.fillna(df2.mean())

 

  • fillna() 메소드를 적용하기 위해 먼저 데이터프레임 객체를 다음과 같이 생성한다.
df = pd.DataFrame([ [np.nan, 2, 0, np.nan], [3, 4, np.nan, 1], [np.nan, 5, np.nan, 2],
[np.nan, 1, 2, 3]], columns=list('ABCD'))
df

 

  • 모든 손실 값을 0으로 대체한다.
  • 파이썬은 NaN실수로 인식하여 0이 아닌 0.0으로 표현하고, B열은 정수로 표현한다.
df.fillna(0)

 

  • non-null 값들을 앞이나 뒤로 브로드캐스팅할 수 있다.
df.fillna(method='ffill')

 

  • 다음과 같이 열 'A', 'B', 'C', 'D'에 있는 모든 손실 값을 각각 0, 1, 2 그리고 3으로 대체할 수 있다.
val = {'A': 0, 'B': 1, 'C': 2, 'D': 3}
df.fillna(value=val)

 

  • 다음과 같이 val 을 기준으로 손실 값을 대체할 수 있다.
  • limit=1은 열을 기준으로 첫 번째 손실 값만 대체하라는 의미이다.
df.fillna(value=val, limit=1)

 

  • 데이터 세트에서 손실 데이터를 갖는 라벨을 제외하려면 drop() 메소드를 사용한다.
df2.iloc[2:3, 2:3] = 2.0
df2

 

df2.dropna(axis=0)

 

df2.dropna(axis=1)

 

>>> df2['two'].dropna()
a    4.0
c    6.0
Name: two, dtype: float64

 

  • 다음은 데이터 타입이 datetime64[ns]인 경우 손실 값을 NaT인 요소로 나타내는 df 객체를 생성한다.
df = pd.DataFrame({'name': ['haena', 'suho', 'naeun'], 'hobby': ['jogging', 'reading', np.nan],
                   'born': [pd.NaT, pd.Timestamp('2001-01-01'), pd.NaT]})
df

 

  • 앞 데이터프레임에서 최소한 1개 요소에 손실 값이 있는 행 또는 열을 제거한다.
df.dropna()

 

df.dropna(axis='columns')

 

  • 다음에서 모든 요소가 손실 값을 가지는 행을 제거하는 옵션을 적용했지만, 해당 사항이 없어 행이 변경되지 않았다.
df.dropna(how='all')

 

  • 이번에는 최소한 2개의 손실 값이 있는 행을 제거한다.
df.dropna(thresh=2)

 

  • 옵션에 해당하는 열에 손실 값이 있는 행을 제거한다.
df.dropna(subset=['name', 'born'])

 

df.dropna(subset=['hobby'])

 

  • dropna() inplace=True 옵션을 입력하면 제거한 손실 값을 반영한 사항을 바로 저장한다.
df.dropna(inplace=True)
df

 

  • 지금까지 손실 값을 대체하기 위해 fillna() 메소드를 사용하였지만, replace() 메소드를 이용해 간단하면서 유연하게 손실 값을 처리할 수도 있다.
>>> ser = pd.Series([0, np.nan, 2, 3, 5])
>>> ser
0    0.0
1    NaN
2    2.0
3    3.0
4    5.0
dtype: float64

>>> ser.replace(np.nan, 1.0)
0    0.0
1    1.0
2    2.0
3    3.0
4    5.0
dtype: float64

 

  • replace() 메소드는 ser 객체의 요소를 대체할 수 있지만, 원래 ser 객체의 요소를 변경할 수는 없다.
    • 복사의 차이점과 유사하다.
>>> ser.replace({np.nan: 1, 5: 4})
0    0.0
1    1.0
2    2.0
3    3.0
4    4.0
dtype: float64

 

  • 여러 요소를 하나의 값으로 대체하려면 리스트를 사용한다.
  • 또한, 리스트를 사용해 해당 요소들을 각각 다른 값으로 대체할 수도 있다.
>>> ser.replace([0, 2], 1)
0    1.0
1    NaN
2    1.0
3    3.0
4    5.0
dtype: float64

>>> ser.replace([np.nan, 5], [1, np.nan])
0    0.0
1    1.0
2    2.0
3    3.0
4    NaN
dtype: float64

 

  • 데이터프레임의 손실 값을 대체할 때는 열을 기준으로 개별 값을 딕셔너리형으로 입력하고 대체하려는 값을 입력한다.
df = pd.DataFrame({'A': [0, 1, np.nan], 'B': [3, 4, 5]})
df.replace({'A': np.nan, 'B': 3}, 10)

 

 

멀티 인덱스(Multi Index)

  • 계층적 인덱스라고도 불린다.
  • 하나의 축에 둘 이상의 인덱스를 지정할 수 있도록 한다.
  • 멀티 인덱싱은 고차원 데이터 행에 대해 열이 여러 인덱스 라벨을 가지는 구조이다.
  • 멀티 인덱싱은 고차원 데이터를 1차원인 시리즈나 데이터프레임 같은 저차원 데이터 구조로 저장하고 관리를 할 수 있게 한다.
  • 멀티 인덱싱을 이용하면 그룹화, 선택 및 재형성 연산을 할 수 있다.
  • 또한, 파일에서 데이터를 읽어 데이터 세트를 준비할 때 원하는 멀티인덱스를 생성할 수 있다.

 

멀티 인덱스 객체 생성

  • 판다스 객체에서는 다음과 같은 방법으로 축의 멀티 인덱스를 생성한다.
    • MultiIndex.from_array() 를 사용하는 배열 리스트
    • MultiIndex.from_tuples() 를 사용하는 튜플 배열
    • MultiIndex.from_product() 를 사용하는 고차 세트의 이터러블
    • MultiIndex.from_frame() 을 사용하는 데이터프레임
  • 인덱스 연산자가 튜플 리스트를 전달 받으면 멀티 인덱스를 반환한다.
>>> li = [['ha', 'ha', 'hi', 'hi', 'ho', 'ho'], ['one', 'two', 'one', 'two', 'one', 'two']]
>>> li1 = list(zip(*li))
>>> li1
[('ha', 'one'),
 ('ha', 'two'),
 ('hi', 'one'),
 ('hi', 'two'),
 ('ho', 'one'),
 ('ho', 'two')]

 

  • MultiIndex 클래스의 from_tuples() 메소드를 이용해 멀티 인덱스 객체를 인수로 하는 시리즈 객체를 생성한다.
>>> ind = pd.MultiIndex.from_tuples(li1, names=['1st', '2nd'])
>>> ind
MultiIndex([('ha', 'one'),
            ('ha', 'two'),
            ('hi', 'one'),
            ('hi', 'two'),
            ('ho', 'one'),
            ('ho', 'two')],
           names=['1st', '2nd'])
           
>>> ser = pd.Series(np.random.randn(6), index=ind)
>>> ser
1st  2nd
ha   one   -0.339264
     two   -0.615008
hi   one   -0.269377
     two    0.187064
ho   one   -0.652559
     two    0.178951
dtype: float64

 

  • MultiIndex.from_product()를 이용해 2개이터러블을 짝지으면 객체를 더 쉽게 생성할 수 있다.
>>> iter = [['ha', 'hi', 'ho'], ['one', 'two']]
>>> pd.MultiIndex.from_product(iter, names=['1st', '2nd'])
MultiIndex([('ha', 'one'),
            ('ha', 'two'),
            ('hi', 'one'),
            ('hi', 'two'),
            ('ho', 'one'),
            ('ho', 'two')],
           names=['1st', '2nd'])

 

  • MultiIndex.from_frame() 메소드를 이용하면 데이터프레임에서 직접 멀티 인덱스 객체를 구성할 수 있다.
    • 이 메소드는 판다스 라이브러리 0.24.0 버전부터 새로 추가되었으므로, 이전 버전에서는 오류가 발생할 수 있다.
>>> df = pd.DataFrame([['ha', 'one'], ['ha', 'two'], ['ho', 'one'], ['ho', 'two']], columns=['1st', '2nd'])
>>> pd.MultiIndex.from_frame(df)
MultiIndex([('ha', 'one'),
            ('ha', 'two'),
            ('ho', 'one'),
            ('ho', 'two')],
           names=['1st', '2nd'])

 

  • 배열 리스트를 직접 시리즈나 데이터프레임에 입력하면 멀티 인덱스를 자동으로 생성할 수 있다.
>>> arr = [ np.array(['ha', 'ha', 'hi', 'hi', 'ho', 'ho']), np.array(['one', 'two', 'one', 'two', 'one', 'two'])]
>>> ser = pd.Series(np.random.randn(6), index=arr)
>>> ser
ha  one    1.338737
    two    1.077762
hi  one    1.539513
    two   -0.106579
ho  one   -1.090840
    two    0.370244
dtype: float64

 

df = pd.DataFrame(np.random.randn(6, 3), index=arr)
df

 

  • 판다스 객체의 행 또는 열 축에 인덱스를 적용할 수 있고, 인덱스 레벨 수는 필요한 만큼 지정할 수 있다.
df = pd.DataFrame(np.random.randn(3, 6), index=['A', 'B', 'C'], columns=ind)
df

 

멀티 인덱스 인덱싱

  • 멀티 인덱스 인덱싱의 주요 특징 중 하나는 데이터 세트에서 서브그룹을 지정하는 인덱스 라벨로 서브 그룹을 생성할 수 있다는 것이다.
df['ha']

 

>>> df['ha']['one']
A    1.588027
B   -2.613225
C   -1.317432
Name: one, dtype: float64

 

  • 시리즈와 데이터프레임의 reindex() 메소드는 다른 멀티 인덱스, 리스트 또는 튜플 배열과 함께 호출할 수 있다.
>>> ser.reindex(ind[:3])
1st  2nd
ha   one    1.338737
     two    1.077762
hi   one    1.539513
dtype: float64

>>> ser.reindex([('ho', 'one'), ('ha', 'two')])
ho  one   -1.090840
ha  two    1.077762
dtype: float64

 

  • loc 속성에 멀티 인덱스를 적용하여 인덱싱 할 수 있으며, 이때 키는 튜플 형태이다.
df = df.T
df

 

>>> df.loc[('ha', 'two')]
A   -1.258368
B   -1.097652
C    0.636064
Name: (ha, two), dtype: float64

 

  • loc 속성을 이용해 특정 열을 인덱싱할 수 있다.
>>> df.loc[('ha', 'two'), 'A']
2.2929073915855724

 

df.loc['ha']

 

  • df 객체를 부분 슬라이싱할 수 있다.
df.loc['ha':'hi']

 

  • 범위를 튜플 형태로 지정해 데이터를 슬라이싱 할 수 있다.
df.loc[('hi', 'two'):('ho', 'one')]

 

df.loc[('hi', 'two'):'ho']

 

  • loc 속성에 라벨이나 튜플의 리스트를 전달하면 인덱스 재배열처럼 작용한다.
df.loc[[('ha', 'two'), ('ho', 'one')]]

 

멀티 인덱스 순서 정렬

  • 효과적인 슬라이싱과 인덱싱을 위해 멀티 인덱스 처리된 객체의 순서를 정렬해야 한다.
  • 먼저 shuffle() 함수를 사용해 li1 객체의 요소들을 섞는다.
>>> li1
[('ha', 'one'),
 ('ha', 'two'),
 ('hi', 'one'),
 ('hi', 'two'),
 ('ho', 'one'),
 ('ho', 'two')]
 
>>> np.random.shuffle(li1)
>>> li1
[('ho', 'one'),
 ('ha', 'two'),
 ('ho', 'two'),
 ('hi', 'one'),
 ('ha', 'one'),
 ('hi', 'two')]

 

  • sort_index() 메소드를 사용해 멀티 인덱스 순서에 맞춰 정렬한다.
>>> ser = pd.Series(np.random.randn(6), index=pd.MultiIndex.from_tuples(li1))
>>> ser
ho  one    1.249362
ha  two    0.409203
ho  two    1.100604
hi  one   -0.441275
ha  one    0.384636
hi  two    2.083151
dtype: float64

>>> ser.sort_index()
ha  one    0.384636
    two    0.409203
hi  one   -0.441275
    two    2.083151
ho  one    1.249362
    two    1.100604
dtype: float64

>>> ser.sort_index(level=0)
ha  one    0.384636
    two    0.409203
hi  one   -0.441275
    two    2.083151
ho  one    1.249362
    two    1.100604
dtype: float64

>>> ser.sort_index(level=1)
ha  one    0.384636
hi  one   -0.441275
ho  one    1.249362
ha  two    0.409203
hi  two    2.083151
ho  two    1.100604
dtype: float64

 

  • set_names() 메소드를 사용하면 멀티 인덱스 레벨에 이름을 설정할 수 있다.
  • sort_index() 메소드에 level 인수를 사용하면 인덱스 레벨 이름의 순서를 정렬할 수 있다.
>>> ser.index.set_names(['1st', '2nd'], inplace=True)
>>> ser.sort_index(level='1st')
1st  2nd
ha   one    0.384636
     two    0.409203
hi   one   -0.441275
     two    2.083151
ho   one    1.249362
     two    1.100604
dtype: float64

>>> ser.sort_index(level='2nd')
1st  2nd
ha   one    0.384636
hi   one   -0.441275
ho   one    1.249362
ha   two    0.409203
hi   two    2.083151
ho   two    1.100604
dtype: float64

 

  • 고차원 객체가 멀티 인덱스를 가지면 level 인수로 특정 축을 정렬할 수 있다.
df

 

df.T.sort_index(level=1, axis=1)

 

728x90
그리드형(광고전용)

'In-depth Study > Pandas' 카테고리의 다른 글

[Pandas] 수학 계산  (0) 2022.05.31
[Pandas] 데이터의 그룹 연산  (0) 2022.05.30
[Pandas] 데이터 가공  (0) 2022.05.29
[Pandas] 데이터 타입과 입출력  (0) 2022.05.27
[Pandas] 판다스의 주요 기능  (0) 2022.05.25
[Pandas] 판다스 데이터 구조  (1) 2022.05.24
[Pandas] 판다스(Pandas) 개요  (0) 2022.05.24
⚠️AdBlock이 감지되었습니다. 원할한 페이지 표시를 위해 AdBlock을 꺼주세요.⚠️


📖 Contents 📖