본문으로 바로가기
TaeyoungKim.dev

pandas loc와 iloc 차이: 필터 후 첫 행이 KeyError가 나는 이유

파이썬작성 약 3분 읽기TaeyoungKim
LinkedInX

데이터를 필터링했더니 표에는 행이 분명히 보이는데 df.loc[0]은 KeyError: 0을 낸다. “첫 행이 있는데 0번 행은 왜 없지?”라는 의문은 pandas의 행 라벨과 현재 위치를 분리하면 풀린다.

loc는 행 라벨, iloc는 현재 위치를 읽는다

도식의 왼쪽 숫자는 행이 가진 라벨이고, 위에서 첫 번째라는 위치는 별도의 값이다. 필터나 정렬 뒤에도 인덱스를 다시 만들지 않았다면 loc[라벨]과 iloc[0]이 서로 다른 행을 가리킬 수 있다.

loc[값]의 값은 인덱스에 붙은 라벨이다. iloc[값]의 값은 화면에 보이는 현재 순서의 정수 위치이며 0부터 시작한다. 처음 만든 DataFrame의 기본 인덱스가 0, 1, 2라면 둘이 우연히 같은 행을 가리킨다. 하지만 필터를 걸면 남은 행의 기존 라벨은 대개 그대로 유지된다.

아래 입력은 설명용 작업 세 건이다. priority가 high인 작업만 남겨 첫 행을 읽어 보자.

python
import pandas as pd

jobs = pd.DataFrame(
    {"job": ["build", "backup", "report"], "priority": ["low", "high", "high"]},
    index=[10, 20, 30],
)
urgent = jobs.loc[jobs["priority"] == "high"]
print(urgent)
print("first position:", urgent.iloc[0]["job"])
print("label 20:", urgent.loc[20]["job"])
text
       job priority
20  backup     high
30  report     high
first position: backup
label 20: backup

필터 결과의 첫 번째 위치는 0이지만 그 행의 라벨은 20이다. urgent.iloc[0]과 urgent.loc[20]은 같은 행을 선택한다. urgent.loc[0]은 라벨 0을 찾다가 실패한다. urgent.iloc[20] 역시 현재 결과에는 두 행뿐이므로 범위를 벗어난다.

빈 결과와 잘못된 라벨을 먼저 구분한다

첫 행 접근이 실패했을 때 무조건 loc을 iloc으로 바꾸면 또 다른 오류를 만들 수 있다. 필터가 0행을 돌려주었다면 iloc[0]도 IndexError다. 먼저 행 수와 인덱스를 함께 출력한다.

python
print("rows:", len(urgent))
print("labels:", urgent.index.tolist())

if urgent.empty:
    print("조건에 맞는 작업이 없습니다")
else:
    print(urgent.iloc[0]["job"])

이 데이터에서는 rows: 2, labels: [20, 30], backup이 나온다. 라벨 0이 없다는 사실과 결과 자체가 비었다는 사실은 다른 문제다. 테스트에는 high가 있는 입력과 없는 입력을 각각 넣어 두 분기가 모두 기대대로 움직이는지 확인한다.

인덱스를 다시 매기거나 원래 라벨을 보존할까?

후속 단계가 오직 필터 결과의 순번만 필요하다면 urgent.reset_index(drop=True)로 0, 1 라벨을 새로 붙일 수 있다. 그다음에는 loc[0]도 첫 행을 가리킨다. 하지만 원본의 20·30이 작업 식별자라면 버리는 순간 원본 행으로 되돌아갈 연결 고리가 사라진다.

python
renumbered = urgent.reset_index(drop=True)
print(renumbered.index.tolist())  # [0, 1]
print(renumbered.loc[0, "job"])  # backup

그래서 처리 순서를 뜻할 때는 iloc, 업무상 식별자나 인덱스 라벨을 뜻할 때는 loc을 명시하는 편이 읽기 쉽다. 중복 라벨이 가능한 데이터에서는 loc[라벨]이 여러 행을 돌려줄 수도 있으니, 라벨을 유일한 키로 사용할지 먼저 확인해야 한다. reset_index는 오류를 가리는 임시 처방이 아니라 인덱스의 의미를 바꾸는 결정이다.

핵심 요약: 첫 행과 라벨 0은 다르다

필터 후에도 남은 행은 원래 라벨을 유지한다. 첫 행을 읽으려면 결과가 비지 않았는지 확인한 뒤 iloc[0]을 쓰고, 원래 라벨을 알고 있다면 loc[라벨]을 쓴다. 둘이 같은 숫자로 동작하는 초기 DataFrame만 보고 같은 기능이라 생각하지 않으면 KeyError의 이유가 바로 보인다.

작성자

TaeyoungKim

기초 개념을 구현과 검증, 실제 운영 판단까지 연결해 기록합니다.

#pandas#DataFrame#loc#iloc#KeyError

함께 읽으면 좋은 글