[Python pandas] DataFrame에서 데이터를 선택할 때 사용하는 loc vs. iloc 비교
Python 분석과 프로그래밍/Python 데이터 전처리 2022. 1. 1. 12:11탐색적 데이터 분석 및 데이터 전처리를 할 때 특정 행과 열을 기준으로 데이터를 선택(selection), 인덱싱(indexing), 슬라이싱(slicing)하는 하는 처리가 필요합니다. 이때 pandas 에서 사용할 수 있는 게 loc, iloc 인데요, 비슷해서 좀 헷갈리는 면이 있습니다.
이번 포스팅에서는 Python pandas 의 DataFrame에서 데이터를 선택(selection), 인덱싱(indexing), 슬라이싱(slicing)할 때 사용하는 loc vs. iloc 를 비교해보겠습니다.
- loc 는 레이블 기반 (label-based) 또는 블리언 배열(boolean array) 기반으로 데이터를 선택
- iloc 는 정수 기반의 위치 (integer-based position) 또는 블리언 배열(boolean array) 기반으로 데이터를 선택
아래의 순서대로 loc vs. iloc 를 간단한 예를 들어 비교하면서 소개하겠습니다.
(1) A Value
(2) A List or Array
(3) A Slice Object
(4) Conditions or Boolean Array
(5) A Callable Function
[ Pandas DataFrame의 데이터를 선택할 때 사용하는 loc vs. iloc ]
먼저, index를 수기 입력해주고, 숫자형과 범주형 변수를 모두 가지는 간단한 예제 pandas DataFrame을 만들어보겠습니다.
## creating a sample pandas DataFrame
import pandas as pd
df = pd.DataFrame({
'name': ['park', 'choi', 'lee', 'kim', 'lim', 'yang'],
'gender': ['M', 'F', 'F', 'M', 'F', 'F'],
'age': [25, 29, 25, 31, 38, 30],
'grade': ['S', 'B', 'C', 'A', 'D', 'S'],
'tot_amt': [500, 210, 110, 430, 60, 680]},
index=['c100', 'c101', 'c102', 'c103', 'c104', 'c105'])
print(df)
# name gender age grade tot_amt
# c100 park M 25 S 500
# c101 choi F 29 B 210
# c102 lee F 25 C 110
# c103 kim M 31 A 430
# c104 lim F 38 D 60
# c105 yang F 30 S 680
아래부터는 loc vs. iloc 코드 예시인데요, 모두 데이터를 선택하는 굉장히 간단한 코드들 이므로 설명은 생략합니다. 특이사항에 대해서만 간략히 부연설명 남겨요.
(1) loc vs. iloc: A Value
한 개의 행 레이블(a single row label)로 loc 를 사용해서 값을 가져오면 pandas Series 를 반환하는 반면에, 리스트(list, [ ]) 안에 1개 행 레이블을 넣어서 loc 를 사용하면 pandas DataFrame을 반환합니다. 이것은 iloc 에 정수 위치를 넣어서 값을 가져올 때도 동일합니다.
## (1) pandas.DataFrame.loc[]
## : Access a group of rows and colmns by label(s) or a boolean array
## (1-1) using a row label --> returns a pandas Series
df.loc['c100']
# name park
# gender M
# age 25
# grade S
# tot_amt 500
# Name: c100, dtype: object
## (1-2) using a list of row label --> returns a pandas DataFrame
df.loc[['c100']]
# name gender age grade tot_amt
# c100 park M 25 S 500
## (2) pandas.DataFrame.iloc[]
## : Purely integer-location based indexing for selection by position.
## (2-1) A scalar of integer --> returns pandas Series
df.iloc[0]
# name park
# gender M
# age 25
# grade S
# tot_amt 500
# Name: c100, dtype: object
## (2-2) A list of integer --> returns pandas DataFrame
df.iloc[[0]]
# name gender age grade tot_amt
# c100 park M 25 S 500
(2) loc vs. iloc: A List or Array
df.loc[['c100', 'c105']] 처럼 loc 에 레이블 리스트를 사용하면 해당 행의 다수의 열의 값을 가져오며, df.loc['c100', 'name'] 처럼 사용하면 레이블 기반의 해당 행(row)과 열(column)의 값을 가져옵니다.
## (1) pandas.DataFrame.loc[]
## : Access a group of rows and colmns by label(s) or a boolean array
## (1-2) using multiple row labels
df.loc[['c100', 'c105']]
# name gender age grade tot_amt
# c100 park M 25 S 500
# c105 yang F 30 S 680
## using row and column label
df.loc['c100', 'name']
# 'park'
## (2) pandas.DataFrame.iloc[]
## : Purely integer-location based indexing for selection by position.
## (2-2) A list or array of integers
df.iloc[[0, 1, 3, 5]]
# name gender age grade tot_amt
# c100 park M 25 S 500
# c101 choi F 29 B 210
# c103 kim M 31 A 430
# c105 yang F 30 S 680
(3) loc vs. iloc: A Slice Object
loc 로 레이블 기반 슬라이싱을 하면 처음과 끝 레이블 값이 포함된 채로 값을 가져옵니다. 예를 들어, 아래의 df.loc['c100':'c103'] 은 'c100'과 'c103' 행도 모두 포함된 값을 가져왔습니다. 반면에 iloc 로 정수 위치 기반으로 슬라이싱을 하면 처음 정수 위치의 행은 가져오지만 마지막의 정수 위치의 행은 가져오지 않습니다.
## (1) pandas.DataFrame.loc[]
## : Access a group of rows and colmns by label(s) or a boolean array
## (1-3) Slice with labels for row and single label for column.
df.loc['c100':'c103', 'name']
# c100 park
# c101 choi
# c102 lee
# c103 kim
# Name: name, dtype: object
## (2) pandas.DataFrame.iloc[]
## : Purely integer-location based indexing for selection by position.
## (2-3) slicing using integer
df.iloc[1:4]
# name gender age grade tot_amt
# c101 choi F 29 B 210
# c102 lee F 25 C 110
# c103 kim M 31 A 430
(4) loc vs. iloc: Conditions or Boolean Array
loc 의 레이블 기반 데이터 선택에는 조건문과 블리언 배열을 모두 사용할 수 있습니다. iloc 의 정수 기반 데이터 선택에는 블리언 배열을 사용할 수 있습니다.
## (1) pandas.DataFrame.loc[]
## : Access a group of rows and colmns by label(s) or a boolean array
## (1-4-1) Conditional that returns a boolean Series
## Boolean list with the same length as the row axis
df['tot_amt'] > 400
# c100 True
# c101 False
# c102 False
# c103 True
# c104 False
# c105 True
# Name: tot_amt, dtype: bool
## Conditional that returns a boolean Series
df.loc[df['tot_amt'] > 400]
# name gender age grade tot_amt
# c100 park M 25 S 500
# c103 kim M 31 A 430
# c105 yang F 30 S 680
## Conditional that returns a boolean Series with column labels specified
df.loc[df['tot_amt'] > 400, ['name']]
# name
# c100 park
# c103 kim
# c105 yang
## (1-4-2) A boolean array
df.loc[[True, False, False, True, False, True]]
# name gender age grade tot_amt
# c100 park M 25 S 500
# c103 kim M 31 A 430
# c105 yang F 30 S 680
## (2) pandas.DataFrame.iloc[]
## : Purely integer-location based indexing for selection by position.
## (2-4) With a boolean mask the same length as the index.
## loc and iloc are interchangeable when labels are 0-based integers.
df.iloc[[True, False, False, True, False, True]]
# name gender age grade tot_amt
# c100 park M 25 S 500
# c103 kim M 31 A 430
# c105 yang F 30 S 680
(5) loc vs. iloc: A Callable Function
lambda 익명함수를 사용하여 호출 가능한 함수를 loc, iloc 에 사용해서 값을 선택할 수 있습니다.
(df.iloc[lambda df: df['tot_amt'] > 400] 은 왜그런지 모르겠는데 에러가 나네요. -_-;)
## (1) pandas.DataFrame.loc[]
## : Access a group of rows and colmns by label(s) or a boolean array
## (1-5) Callable that returns a boolean Series
df.loc[lambda df: df['tot_amt'] > 400]
# name gender age grade tot_amt
# c100 park M 25 S 500
# c103 kim M 31 A 430
# c105 yang F 30 S 680
## (2) pandas.DataFrame.iloc[]
## : Purely integer-location based indexing for selection by position.
## (2-7) Callable that returns a boolean Series
df.iloc[lambda x: x.index == 'c100']
# name gender age grade tot_amt
# c100 park M 25 S 500
[ Reference ]
* pandas DataFrame에서 행, 열 데이터 선택: https://rfriend.tistory.com/282
* pandas loc: https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.loc.html
* pandas iloc: https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.iloc.html
이번 포스팅이 많은 도움이 되었기를 바랍니다.
행복한 데이터 과학자 되세요! :-)