탐색적 데이터 분석 및 데이터 전처리를 할 때 특정 행과 열을 기준으로 데이터를 선택(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 ]

selecting data in pandas DataFrame using 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   

 

 

이번 포스팅이 많은 도움이 되었기를 바랍니다. 

행복한 데이터 과학자 되세요!  :-)

 

728x90
반응형
Posted by Rfriend
,