작성자: admin 작성일시: 2016-07-08 23:58:23 조회수: 2376 다운로드: 137
카테고리: Python 태그목록:

Pandas 인덱서

Pandas는 numpy 행렬과 같이 쉼표를 사용한 (행 인덱스, 열 인덱스) 형식의 인덱싱을 지원하기 위해 다음과 같은 특별한 인덱서를 제공한다.

  • loc : 라벨 기반의 복수 인덱싱
  • iloc : 숫자 기반의 복수 인덱싱

loc 인덱서

loc 인덱서는 (행 인덱스, 열 인덱스) 형식의 인덱싱을 할 수 있지만 행/열 인덱서들이 모두 다음 중 하나이어야 한다.

  • 정수 인덱스가 아닌 라벨 값(원래가 정수 인덱스인 경우는 예외)
  • 라벨 값의 리스트
  • 라벨 값의 슬라이싱
  • 불리언 리스트, 1차원 배열, 시리즈 (데이터프레임은 안된다.)
  • 또는 데이터프레임을 입력으로 받고 위의 값을 반환하는 함수
In:
df = pd.DataFrame(np.arange(10, 22).reshape(3, 4),
                  index=["a", "b", "c"],
                  columns=["A", "B", "C", "D"])
df
Out:
A B C D
a 10 11 12 13
b 14 15 16 17
c 18 19 20 21
In:
df.loc["a", "A"]
Out:
10
In:
df.loc["b":, "A"]
Out:
b    14
c    18
Name: A, dtype: int64
In:
df.loc["a", :]
Out:
A    10
B    11
C    12
D    13
Name: a, dtype: int64
In:
df.loc[["a", "b"], ["B", "D"]]
Out:
B D
a 11 13
b 15 17
In:
df.loc[df.A > 10, :]
Out:
A B C D
b 14 15 16 17
c 18 19 20 21

loc 인덱서를 사용하면 하나의 행을 시리즈 자료형으로 뽑아낼 수 있다. 만약 loc 인덱서를 사용하지 않으면 슬라이싱을 해야 하는데 이 경우에는 데이터프레임 자료형을 반환한다.

In:
df.loc["a", :]
Out:
A    10
B    11
C    12
D    13
Name: a, dtype: int64
In:
df[:1]  # loc 인덱서를 사용하지 않는 경우
Out:
A B C D
a 10 11 12 13
In:
# df.loc[:, df[:1] <= 11]  # 데이터프레임은 loc 인덱서에 넣을 수 없으므로 에러!
df.loc[:, df.loc["a", :] <= 11] # 이렇게 해야 한다.
Out:
A B
a 10 11
b 14 15
c 18 19
In:
def find_rows(df):
    return df.A > 12
In:
find_rows(df)
Out:
a    False
b     True
c     True
Name: A, dtype: bool
In:
df.loc[find_rows(df), ["C"]]
Out:
C
b 16
c 20

만약 loc 인덱서를 사용하면서 인덱스를 하나만 넣을 경우에는 행(row)을 선택한다.

In:
df.loc["a"]
Out:
A    10
B    11
C    12
D    13
Name: a, dtype: int64
In:
df.loc["e"] = [90, 91, 92, 93]
df
Out:
A B C D
a 10 11 12 13
b 14 15 16 17
c 18 19 20 21
e 90 91 92 93

iloc 인덱서

iloc 인덱서는 loc 인덱서와 반대로 라벨이 아닌 정수 인덱스만 받는다.

In:
df.iloc[0, 1]
Out:
11
In:
df.iloc[:2, 2]
Out:
a    12
b    16
Name: C, dtype: int64
In:
df.iloc[0, -2:]
Out:
C    12
D    13
Name: a, dtype: int64
In:
df.iloc[2:3, 1:3]
Out:
B C
c 19 20

loc 인덱서와 마찬가지로 인덱스가 하나만 들어가면 행을 선택한다.

In:
df.iloc[-1]
Out:
A    90
B    91
C    92
D    93
Name: e, dtype: int64
In:
df.iloc[-1] = df.iloc[-1] * 2
df
Out:
A B C D
a 10 11 12 13
b 14 15 16 17
c 18 19 20 21
e 180 182 184 186

연습 문제 1

  1. 모든 행과 열에 label을 주어 5 x 5 이상의 크기를 가지는 DataFrame을 만든다.
  2. 10가지 이상의 방법으로 특정한 행과 열을 선택한다.

질문/덧글

label 미지정시 than*** 2016년 7월 19일 5:40 오후

Label이 지정되지 않는 경우에는 integer slicing을 label slicing으로 간주하여 마지막 값을 포함한다

df.columns = ["c1", "c2", "c3"]
df.ix[0:2, 1:2]

이렇게 코딩을 한 경우 마지막값을 포함하려면
row는 0,1,2 <-- 이렇게 표기되고
column은 1,2 <-- 이렇게 표기되는게 맞는거같은데

column의 경우 마지막값인 2만 나오고 1은 출력되지 않는데 제가 무얼 놓치고 있는건가요?

답변: label 미지정시 관리자 2016년 7월 19일 9:38 오후

row index 의 경우에는 인덱스가 라벨인지 정수인지 알 수 없기 때문에 라벨로 가정하여 0, 1, 2 행이 표시됩니다.
column index 의 경우에는 라벨일 아니라 정수라는 것이 명확하므로 하나만 나오게 됩니다.