본문 바로가기
데이터분석과 AI/파이썬을 엑셀처럼 쓰기

6. DataFrame에 필터 걸기(loc, iloc)

by 우공80 2022. 9. 25.
728x90

데이터프레임에 필터걸기

이제 본격적으로 Excel처럼 Python을 사용해 보겠습니다.

컬럼별 설명
BostonHousing 데이터의 컬럼별 설명

우리가 사용할 BostonHousing 데이터는 위와 같은 칼럼들을 가지고 있습니다.

여기서 주택 가격이 21.6인 데이터를 뽑는다고 하면 어떻게 할까요?

Excel에서는 어떤 기능을 쓰지요? 네 바로 필터입니다. 

값에 21.6 넣고 Enter키 누르면 바로 결과가 나옵니다.

엑셀 필터 걸기

 

 

그럼 Python은 어떻게 할까요? iloc, loc입니다. 

 

공식문서
iloc: https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.iloc.html#pandas-dataframe-iloc
loc: https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.loc.html

자세한 것은 공식문서를 참고하시면 되고..  간단한 것만 짚고 넘어가자면,

iloc는 정수 기반 인덱스를 이용하는 것이고, loc는 레이블 위치기반 인덱스라고 공식문서에 나와있습니다. 

이게 무슨 의미인가 싶은데, 그냥 행 번호와 인덱스 값이라고 보시면 됩니다.  (밑에 에제에서 정확히 확인하겠습니다.)

 

사용법은 아래와 같습니다. loc뒤에 소괄호()가 없고, 대괄호[]만 사용한다는 것을 유념하세요.(매번 헷갈릴 수 있음)

데이터프레임. loc [행 조건, 열 조건]

 

위의 Excel의 예처럼 loc 함수로 MEDV값이 21.6인 데이터를 추출하려면 아래와 같이 추출이 가능합니다.

#데이터프레임.loc[데이터프레임[컬럼명]==찾는 값]
boston_price.loc[boston_price['MEDV']==21.6]

대충 boston_price의 MEDV 칼럼 값이 21.6과 같은 것을 찾아오라는 코드입니다.

loc 추출 결과

여기에서  만약 MEDV 값만 추출한다면 어떻게 할까요? loc에서는 다음과 같습니다. 

#데이터프레임.loc[데이터프레임[컬럼명]==찾는 값],컬럼명]
boston_price.loc[boston_price['MEDV']==21.6,'MEDV']

loc 특정값을 가지는 특정 컬럼만 추출

즉, 행, 열 중 제외해도 되는 조건은 제외해도 무방합니다. 조건과 상관없이 'MEDV' 칼럼만 추출한다면?

이때는 행 부분을 ":"을 넣으면 됩니다. ":"는 전체 행을 모두 선택한다는 뜻입니다. 

#데이터프레임.loc[:,컬럼명]
boston_price.loc[:,'MEDV']

loc 특정 컬럼만 추출

그럼 0에서 10행까지만 선택한다고 하면 어떻게 할까요?

#데이터프레임.loc[시작 인텍스명:끝 인덱스명,컬럼명]
boston_price.loc[0:10,'MEDV']

행 인덱싱

여기에서 주의할 것은 0,10은 인덱스 값을 의미하는 것이고 인덱스에 따른 정수 위치가 아니라는 점입니다.

이 것을 확인하기 위해 아래와 같이 index를 문자열로 변경한 bdt 데이터프레임을 만들었습니다. 이 데이터프레임은 boston_price와 index 빼고 모두 동일합니다.

bdt=boston_price.copy()
bdt=bdt.reset_index()
bdt['index']=bdt['index'].apply(lambda x:'index_'+str(x))
bdt=bdt.set_index('index')

index를 변경한 bdt 데이터 프레임
index를 변경한 bdt 데이터프레임

아래와 같이 index를 변경한 bdt 데이터프레임에서 아까와 동일하게 loc를 사용하면 에러가 발생합니다.

bdt.loc[0:10,'MEDV']

loc 에러

정수형(Int) 타입으로 인덱싱을 못한다는 에러입니다. 아래와 같이 인덱스 값을 넣어주어야 정상 출력됩니다.

bdt.loc['index_0':'index_10','MEDV']

loc 정상 결과 출력

iloc를 사용하면 어떻게 될까요? 순수한 정수 기반 인덱싱이라고 했으니 잘 되겠죠?

bdt.iloc[0:10,'MEDV']

iloc 에러

엥? 근데 여기도 에러가 납니다. 읽어보니 iloc는 정수 또는 그에 준하는 값만 넣을 수 있다는 이야기입니다.

이 에러는 열을 선택하는 부분에서 "MEDV"를 넣었기 때문입니다. 이것을 정수로 변경해 주면 됩니다.

앞에서부터 세어서 정수를 넣어주어도 되고 (0부터 시작) 끝에서 부터 세어서 마이너스 표시로 넣어주어도 됩니다. (-1)부터 시작 "MEDV"는 전체 컬럼 중 가장 끝에 있으니 "-1"이 됩니다.

bdt.iloc[0:10,-1]

iloc 정상 조회

자 이렇게 원하는 결과가 나왔습니다.

 

그럼 이렇게 기본적인 부분은 해보았고, 이번에는 조건을 넣어서 데이터를 추출해 보겠습니다.

 

MEDV가 전체 평균 이하인 데이터만 뽑는다고 하면 어떻게 할까요?

엑셀에서는 아래와 같이 조건을 넣어 필터링을 하면 됩니다. 

엑셀 필터링 방법엑셀 필터 결과
이 포스팅을 작성하는 PC에 엑셀이 안깔려있어서 구글 스프레드시트를 썼습니다.

Python에서는 아래와 같이 쓰면 됩니다.

#DataFrame.loc[DataFrame[컬럼명] <= 비교값]
boston_price.loc[boston_price['MEDV']<=boston_price['MEDV'].mean()]

조건에 따른 loc 함수 사용 결과

만약 일부 열만 추출하고 싶다면, Excel은 열을 범위 선택하면 되고, Python은 아래처럼 추출하고자 하는 열 또는 열의 리스트로 넣어주면 됩니다. 

boston_price.loc[boston_price['MEDV']<=boston_price['MEDV'].mean(),['RM','AGE','DIS']]

조건으로 행추출&#44; 리스트로 컬럼 선택

이렇게 loc와 iloc에 대한 간단한 예제를 해보았습니다. 

지금 배운 것 중에 "슬라이싱"에 대해서는 제대로 설명드리지 않았습니다.

이 부분은 별도로 포스팅하여 링크를 걸도록 하겠습니다. 

 

감사합니다.

728x90

댓글