[Python] 데이터 사이언스 스쿨 - 4.3 데이터프레임 고급 인덱싱

Updated:

데이터 사이언스 스쿨 자료를 토대로 공부한 내용입니다.

실습과정에서 필요에 따라 내용의 누락 및 추가, 수정사항이 있습니다.


4.3 데이터프레임 고급 인덱싱

데이터 프레임의 인덱싱을 좀 더 편하게 할 수 있는 2개의 인덱서가 있다.

  • loc() : 라벨값 기반의 2차원 인덱싱

  • iloc() : 순서를 나타내는 정수 기반의 2차원 인덱싱

loc 인덱서

앞서 4.1 판다스 패키지의 소개에서 데이터 프레임은 기본적으로 열을 기준으로 인덱싱을 수행하였다.

loc 인덱서와 밑에 나올 iloc 인덱서는 인덱싱 값이 하나인 경우 행을 기준으로 인덱싱 한다.

loc 인덱서로도 슬라이싱 배열 인덱싱 방법 등은 큰 차이가 없다.

import numpy as np
import pandas as pd
df = pd.DataFrame(np.arange(10, 26).reshape(4, 4),
                  index=["a", "b", "c", "d"],
                  columns=["A", "B", "C", "D"])
df
A B C D
a 10 11 12 13
b 14 15 16 17
c 18 19 20 21
d 22 23 24 25

인덱싱 값이 하나인 경우

# .loc[행 인덱스]
df.loc["a"]
A    10
B    11
C    12
D    13
Name: a, dtype: int32
# 슬라이싱
df.loc["b":]
A B C D
b 14 15 16 17
c 18 19 20 21
d 22 23 24 25
df.loc["b":"c"]
A B C D
b 14 15 16 17
c 18 19 20 21
  • loc 인덱서가 아니어도 라벨 슬라이싱의 경우 마지막 지정까지 포함해서 출력한다.
df2 = pd.DataFrame(np.arange(10, 26).reshape(4, 4), columns=["A", "B", "C", "D"])
df2
A B C D
0 10 11 12 13
1 14 15 16 17
2 18 19 20 21
3 22 23 24 25
df2.loc[1:2]
A B C D
1 14 15 16 17
2 18 19 20 21
  • loc 인덱서는 행 인덱스가 정수여도 라벨 슬라이싱처럼 마지막 지정까지 포함해서 출력한다.

  • 애초에 loc 인덱서는 라벨 기반 인덱싱이므로 정수가 아닌 문자로 인식한다고 생각하면 편할 듯하다.

# 여러 행 인덱스 출력
df.loc[["b", "d"]]
A B C D
b 14 15 16 17
d 22 23 24 25
# df["A"] > 15 와 같음
df.A > 15

# Boolean을 이용한 배열 인덱싱
df.loc[df.A > 15]
A B C D
c 18 19 20 21
d 22 23 24 25
  • loc 인덱서 기능은 아니지만 그동안 열 인덱싱을 수행할 때 대괄호로 열 이름을 지정해서 추출하였다.

  • 대괄호를 사용하지 않고 속성값으로 열 이름을 지정해서 추출 가능하다.

  • 불린 시리즈로 배열 인덱싱 하는 경우 불린 시리즈와 데이터 프레임의 행 인덱스가 같아야함을 기억하자.

# 인덱스 값을 반환하는 함수
def select_rows(df):
    return df.A > 15

select_rows(df)

# 인덱스 값을 반환하는 함수를 넣어도 출력이 가능
df.loc[select_rows(df)]
A B C D
c 18 19 20 21
d 22 23 24 25

인덱싱 값이 행과 열 모두인 경우

인덱싱 값이 행과 열 모두인 경우 방법은 넘파이 2차원 배열과 동일하다.

# loc[행 인덱스, 열 인덱스]
df.loc["c", "A"]
18
# 슬라이싱, 리스트
df.loc["b":"c", ["A","D"]]
A D
b 14 17
c 18 21
# 행 인덱스 불린 시리즈
df.loc[df.A > 10, ["C", "A"]]
C A
b 16 14
c 20 18
d 24 22

iloc 인덱서

loc 인덱서는 라벨을 기준으로 인덱싱 한다면 iloc는 정수 기반 인덱싱이다.

df.iloc[1:2]
A B C D
b 14 15 16 17
  • iloc 인덱서는 정수 기반 인덱싱이므로 당연히 슬라이싱은 라벨 슬라이싱이 아니다.

  • 위 예시를 보면 2번째 행만 출력되었음을 확인 할 수 있다.

# 자료(행) 갱신 loc
df.loc["a"] = df.loc["a"] * -1
df
A B C D
a -10 -11 -12 -13
b 14 15 16 17
c 18 19 20 21
d 22 23 24 25
# 자료(행) 갱신
df.iloc[0] = df.iloc[0] * -1
df
A B C D
a 10 11 12 13
b 14 15 16 17
c 18 19 20 21
d 22 23 24 25
  • loc, iloc 인덱서를 이용해서 행 단위로 데이터 갱신이 가능하다.

연습 문제 4.3.1

  1. 모든 행과 열에 라벨을 가지는 5 x 5 이상의 크기를 가지는 데이터프레임을 만든다.

  2. 10가지 이상의 방법으로 특정한 행과 열을 선택한다.

# 1. 데이터 프레임 생성
data = pd.DataFrame(np.arange(30).reshape(5,6),
                    index = ["a", "b", "c", "d", "e"],
                    columns = ["c1", "c2", "c3", "c4", "c5", "c6"])
data
c1 c2 c3 c4 c5 c6
a 0 1 2 3 4 5
b 6 7 8 9 10 11
c 12 13 14 15 16 17
d 18 19 20 21 22 23
e 24 25 26 27 28 29
# 2. 특정 행과 열 선택 (1) - 특정 행 선택
data.loc["a"]
c1    0
c2    1
c3    2
c4    3
c5    4
c6    5
Name: a, dtype: int32
# 2. 특정 행과 열 선택 (2) - 특정 열 선택
data.loc[ :, "c1"]
a     0
b     6
c    12
d    18
e    24
Name: c1, dtype: int32
# 2. 특정 행과 열 선택 (3) - 일부 행 선택
data.loc["c":"e"]
c1 c2 c3 c4 c5 c6
c 12 13 14 15 16 17
d 18 19 20 21 22 23
e 24 25 26 27 28 29
# 2. 특정 행과 열 선택 (4) - 일부 열 선택
data.loc[:,"c3":"c6"]
c3 c4 c5 c6
a 2 3 4 5
b 8 9 10 11
c 14 15 16 17
d 20 21 22 23
e 26 27 28 29
# 2. 특정 행과 열 선택 (5) - 리스트 이용 행 선택
data.loc[["a","d"]]
c1 c2 c3 c4 c5 c6
a 0 1 2 3 4 5
d 18 19 20 21 22 23
# 2. 특정 행과 열 선택 (6) - 리스트 이용 열 선택
data.loc[:, ["c2","c4"]]
c2 c4
a 1 3
b 7 9
c 13 15
d 19 21
e 25 27
# 2. 특정 행과 열 선택 (7) - Boolean 시리즈 이용 행 선택
data.loc[(data["c1"] > 11) & (data.c4 > 20)]
c1 c2 c3 c4 c5 c6
d 18 19 20 21 22 23
e 24 25 26 27 28 29
# 2. 특정 행과 열 선택 (8) - 함수 이용 행 선택
def c1(df):
    return df.c1 > 11

def c4(df):
    return df.c4 > 20
    
data.loc[c1(data) & c4(data)]
c1 c2 c3 c4 c5 c6
d 18 19 20 21 22 23
e 24 25 26 27 28 29
# 2. 특정 행과 열 선택 (9) - 홀수 행 선택
odd = list(range(0,len(data),2))

data.iloc[odd]
c1 c2 c3 c4 c5 c6
a 0 1 2 3 4 5
c 12 13 14 15 16 17
e 24 25 26 27 28 29
# 2. 특정 행과 열 선택 (10) - 짝수 행 선택
add = list(range(1,len(data),2))

data.iloc[add]
c1 c2 c3 c4 c5 c6
b 6 7 8 9 10 11
d 18 19 20 21 22 23

Leave a comment