메뉴 닫기

pandas KeyError, IndexError 해결 가이드 – loc, iloc로 존재하지 않는 레이블과 위치 오류 잡기

pandas KeyError, IndexError 해결 가이드 – loc, iloc로 존재하지 않는 레이블과 위치 오류 잡기

🐍 KeyError와 IndexError가 터지는 진짜 이유와 깔끔한 처방을 한 번에 정리합니다

데이터를 깔끔하게 다듬고 분석 흐름을 이어가려는 순간, 갑작스러운 KeyError나 IndexError가 흐름을 끊어버린 경험이 한두 번이 아니죠.
설정이 잘못된 걸까, 파일에 컬럼이 빠진 걸까, 아니면 선택 메서드 사용법을 제대로 이해하지 못한 걸까 하는 의문이 꼬리에 꼬리를 물곤 합니다.
겉보기엔 비슷한 두 오류지만 원인과 해결책은 분명히 다르고, 재현과 예방까지 고려하면 체크할 지점도 체계적으로 정리할 수 있습니다.
이번 글은 실제 현장에서 자주 마주치는 패턴을 기준으로, 존재하지 않는 레이블을 찾을 때와 범위를 벗어난 위치를 집는 상황을 구분하고, 안전한 선택 규칙으로 사고를 줄이는 방법을 친근하게 안내합니다.

핵심은 pandas의 인덱싱 철학을 이해하고, loc와 iloc, at와 iat의 역할을 정확히 구분하는 데 있습니다.
또한 스키마 변화에 대비한 방어적 코딩, 사전 검증, 예외 처리 패턴을 갖추면 배포 환경에서도 안정성이 크게 올라갑니다.
이 글은 KeyError와 IndexError의 차이, 재현 가능한 최소 예제, 단계별 해결 가이드, 그리고 팀 코드에 곧바로 적용할 수 있는 체크리스트까지 담아 실전 중심으로 정리합니다.
읽고 나면 ‘왜 실패했는지’뿐 아니라 ‘어떻게 예방할지’까지 손에 잡히도록 구성했습니다.



🔗 KeyError와 IndexError 개념과 발생 원인

pandas에서 KeyError는 존재하지 않는 레이블(label)을 찾을 때 발생합니다.
즉, 열 이름이나 인덱스 이름이 정확히 일치하지 않거나, 대소문자/공백/타입이 달라 매칭이 실패하는 경우가 대표적입니다.
반면 IndexError는 정수 위치(position)가 유효 범위를 벗어날 때 나옵니다.
둘의 차이는 무엇을 기준으로 선택했는가로 정리됩니다.
레이블 기반 선택인 loc/at은 KeyError, 위치 기반 선택인 iloc/iat는 IndexError와 연결됩니다.
개념을 나눠 이해하면 오류 메시지만으로도 원인을 빠르게 역추적할 수 있습니다.

CODE BLOCK
import pandas as pd

df = pd.DataFrame({
    "city": ["Seoul", "Busan", "Incheon"],
    "pop": [950, 340, 290]
}, index=["KR-11", "KR-26", "KR-28"])

# 1) KeyError: 존재하지 않는 '열' 또는 '인덱스 레이블'
df["population"]           # 열 레이블 불일치 → KeyError
df.loc["KR-99"]            # 인덱스 레이블 없음 → KeyError
df.loc[:, "POP"]           # 대소문자 차이 → KeyError

# 2) IndexError: 정수 위치가 범위를 벗어남
df.iloc[5]                 # 행 범위 초과 → IndexError
df.iloc[:, 3]              # 열 위치 초과 → IndexError

# 참고: 슬라이싱 규칙
# loc 라벨 슬라이스는 양 끝 포함 (inclusive), iloc 정수 슬라이스는 파이썬 규칙대로 끝 제외
df.loc["KR-11":"KR-28"]
df.iloc[0:2]

💬 핵심 구분: 레이블이면 KeyError, 위치이면 IndexError.
선택기(loc/at ↔ iloc/iat)와 데이터의 존재 범위를 먼저 확인하면 진단 속도가 크게 빨라집니다.

구분 설명
KeyError 존재하지 않는 레이블 접근.
loc, at, 열 이름, 인덱스 이름 불일치에서 주로 발생.
IndexError 유효 범위를 벗어난 정수 위치 접근.
iloc, iat 사용 시 인덱스 초과에서 주로 발생.
  • 🛠️선택기가 레이블(loc/at)인지 위치(iloc/iat)인지 먼저 확인.
  • ⚙️df.columns, df.index로 존재 여부·철자·대소문자 점검.
  • 🔌위치 접근일 경우 len(df)df.shape로 범위 경계 확인.

💡 TIP: CSV 로드 후 컬럼 자동 변환으로 공백이나 BOM이 끼어 KeyError가 날 수 있습니다.
df.columns = df.columns.str.strip()과 같은 전처리로 공백을 제거하면 사고를 줄일 수 있습니다.

⚠️ 주의: loc 라벨 슬라이스는 양 끝을 포함합니다.
반면 iloc 슬라이스는 파이썬 규칙대로 끝을 제외합니다.
두 규칙을 혼동하면 예상치 못한 범위 선택으로 후속 단계에서 IndexError가 연쇄적으로 발생할 수 있습니다.

결론적으로, KeyError/IndexError는 pandas가 데이터를 찾지 못했다는 같은 메시지처럼 보이지만, 기준 축이 다릅니다.
레이블을 조회했다면 철자·대소문자·공백·타입을, 위치를 조회했다면 배열 길이와 경계를 점검하세요.
간단한 검증만으로도 재현과 복구가 쉬워지고, 데이터 공급원이 바뀌어도 안정적인 인덱싱 습관을 유지할 수 있습니다.

🛠️ loc iloc at iat 차이와 안전한 선택 규칙

pandas의 데이터 선택기 네 가지, loc, iloc, at, iat는 구조적으로 같은 역할을 하지만, 내부 로직과 처리 기준은 전혀 다릅니다.
이 구분을 명확히 이해하면 KeyError와 IndexError 대부분을 사전에 방지할 수 있습니다.
실제로 pandas의 공식 문서에서도 “인덱싱 오류의 80%는 잘못된 선택기 사용”에서 비롯된다고 언급할 정도입니다.

🧩 loc와 iloc의 근본적 차이

loc레이블(label) 기반 선택기입니다.
인덱스나 컬럼 이름이 정확히 일치해야 하며, 존재하지 않으면 KeyError를 발생시킵니다.
반대로 iloc정수 위치(integer position) 기반으로 동작합니다.
0부터 시작하는 순번 인덱스를 사용하며, 범위를 벗어나면 IndexError가 납니다.

CODE BLOCK
df = pd.DataFrame({
    "city": ["Seoul", "Busan", "Incheon"],
    "pop": [950, 340, 290]
}, index=["KR-11", "KR-26", "KR-28"])

# loc - 레이블 기반
df.loc["KR-11", "pop"]   # OK
df.loc["KR-99", "pop"]   # KeyError (레이블 없음)

# iloc - 위치 기반
df.iloc[0, 1]             # OK
df.iloc[5, 1]             # IndexError (범위 초과)

⚡ at와 iat의 고속 단일 접근

atiat은 각각 lociloc의 단일 값 버전입니다.
즉, 하나의 스칼라 값을 빠르게 조회하거나 변경할 때 사용합니다.
속도가 빠르지만, 범위를 벗어나면 동일하게 KeyError 또는 IndexError가 발생합니다.

💎 핵심 포인트:
속도는 at/iat가 더 빠르지만, 예외 처리까지 고려해야 한다면 loc/iloc이 더 안전합니다.

메서드 기준 오류 유형 용도
loc 레이블 KeyError 일반적인 행·열 선택
iloc 정수 위치 IndexError 순서 기반 접근
at 레이블 KeyError 단일 셀 빠른 접근
iat 정수 위치 IndexError 단일 셀 빠른 접근
  • 🧠레이블 접근: loc, at — KeyError 가능성
  • ⚙️위치 접근: iloc, iat — IndexError 가능성
  • 🧩단일 셀이라면 at, iat으로 속도 최적화 가능

정리하자면, KeyError와 IndexError는 단순히 “데이터가 없다”는 오류가 아니라, 선택기의 철학과 밀접한 설계상의 신호입니다.
선택기를 혼용하지 않고 정확히 구분하는 습관이 pandas 안정성의 출발점이 됩니다.



⚙️ KeyError 해결 가이드 존재하지 않는 레이블 다루기

KeyError는 pandas에서 가장 흔히 마주치는 예외 중 하나입니다.
주로 존재하지 않는 열 이름이나 인덱스 레이블을 찾으려 할 때 발생합니다.
CSV 또는 Excel 파일을 불러온 뒤 컬럼명이 예상과 다르거나, 공백이나 대소문자 차이, 혹은 한글 인코딩 이슈로 인해 불일치가 생길 때 자주 나타납니다.
이 오류는 단순히 “없는 값을 찾는다”는 문제를 넘어, 데이터 전처리 단계의 품질을 보여주는 중요한 신호이기도 합니다.

🧠 원인 1. 컬럼명 불일치

가장 흔한 경우는 CSV 파일의 컬럼 이름이 예상과 다르게 저장된 경우입니다.
공백이나 특수문자가 포함된 컬럼명은 육안으로는 같아 보여도 pandas에서는 다른 문자열로 인식됩니다.

CODE BLOCK
df = pd.read_csv("data.csv")

# KeyError 예시
df["Age"]  # 실제 컬럼은 " Age" 또는 "age"일 가능성

# 점검 코드
print(df.columns.tolist())

# 해결 방법
df.columns = df.columns.str.strip().str.lower()
df["age"]  # 정상 접근

💡 TIP: df.columns.str.strip()으로 공백을 제거하고, str.lower()로 소문자 통일을 하면 KeyError 발생 확률을 대폭 줄일 수 있습니다.

🧩 원인 2. 존재하지 않는 인덱스 접근

인덱스 레이블이 정확히 일치하지 않거나 누락된 경우에도 KeyError가 발생합니다.
특히 loc 접근 시 문자열 레이블의 오타, 혹은 데이터프레임 인덱스가 숫자형인데 문자열로 접근하는 경우가 대표적입니다.

CODE BLOCK
df = pd.DataFrame({"value": [10, 20, 30]}, index=[101, 102, 103])

df.loc[102]      # 정상
df.loc["102"]    # KeyError (인덱스 타입 불일치)

# 해결책 1: 인덱스 타입 통일
df.index = df.index.astype(str)

# 해결책 2: 존재 여부 확인
if "102" in df.index:
    print(df.loc["102"])
else:
    print("존재하지 않는 인덱스입니다.")

💬 KeyError는 존재하지 않는 ‘이름’을 찾는다는 점을 잊지 마세요.
오류가 발생했다면 우선 df.columnsdf.index를 출력해 실제 구조를 확인하는 것이 첫 단계입니다.

🧾 예외 처리로 안전하게 다루기

코드 실행 중 KeyError가 발생할 가능성이 있다면 try-except 블록으로 감싸 예외를 처리하는 것이 좋습니다.
이는 배포 환경에서 데이터 스키마가 예고 없이 바뀌는 경우 특히 유용합니다.

CODE BLOCK
try:
    value = df.loc["KR-99", "pop"]
except KeyError:
    print("⚠️ 존재하지 않는 레이블입니다. 기본값 0을 반환합니다.")
    value = 0

  • 🔎df.columnsdf.index를 항상 먼저 점검
  • 🧩컬럼명은 .str.strip().str.lower()로 표준화
  • 🧰try-except 블록으로 방어적 접근

KeyError는 pandas를 다루는 모든 단계에서 만날 수 있는 기본 예외지만, 원인을 정확히 알면 가장 쉽게 예방할 수 있는 오류이기도 합니다.
‘존재하지 않는 이름’이라는 관점을 유지하면 어떤 상황에서도 당황하지 않고 원인을 빠르게 찾을 수 있습니다.

🔌 IndexError 해결 가이드 범위를 벗어난 위치 다루기

IndexError는 정수 위치 기반 선택에서만 발생합니다.
pandas에서 iloc 또는 iat으로 행과 열을 접근할 때, 지정한 인덱스 번호가 데이터의 실제 범위를 벗어나면 발생하죠.
즉, “존재하지 않는 순번”을 요청했을 때 일어나는 예외입니다.
이 오류는 KeyError보다 덜 흔하지만, 데이터 병합이나 슬라이싱, 루프 내 인덱싱 중에 종종 불쑥 나타나곤 합니다.

📏 범위를 벗어난 인덱스 접근

데이터프레임에 3개의 행이 있을 때, 0, 1, 2까지 접근은 가능하지만 3을 요청하면 IndexError가 납니다.
파이썬의 리스트 인덱싱 규칙과 동일하게, 끝 인덱스는 포함되지 않습니다.

CODE BLOCK
df = pd.DataFrame({
    "city": ["Seoul", "Busan", "Incheon"],
    "pop": [950, 340, 290]
})

# IndexError 예시
df.iloc[3]      # 행 범위 초과
df.iloc[:, 2]   # 열 범위 초과

# 해결책: len(df)와 df.shape 확인
print(len(df))     # 행 개수
print(df.shape)    # (행, 열)

💬 iloc은 0부터 시작해 n-1까지만 유효합니다.
데이터 개수를 초과하는 정수 인덱스는 항상 IndexError를 일으킵니다.

🧠 동적 루프에서의 IndexError

for 루프나 while 문에서 인덱스를 동적으로 계산할 때, 데이터 크기보다 큰 값을 참조하면 IndexError가 발생합니다.
이 경우에는 루프 조건문을 조정하거나, try-except 블록으로 안전하게 처리할 수 있습니다.

CODE BLOCK
for i in range(len(df) + 2):
    try:
        print(df.iloc[i, 0])
    except IndexError:
        print(f"⚠️ {i}번째 행은 존재하지 않습니다.")

🧩 슬라이싱과 범위 안전성

슬라이싱에서는 끝 인덱스를 벗어나도 IndexError가 발생하지 않습니다.
iloc의 슬라이스는 파이썬 규칙을 그대로 따르므로, 범위를 벗어나면 자동으로 자르고 반환합니다.
따라서 슬라이싱은 개별 인덱스 접근보다 안전합니다.

CODE BLOCK
df.iloc[1:10]   # IndexError 없음, 자동으로 잘림

💎 핵심 포인트:
iloc으로 슬라이싱을 사용할 때는 범위 초과 걱정 없이 안전하게 코드를 실행할 수 있습니다.
하지만 개별 인덱스 접근 시에는 반드시 길이 검증을 해야 합니다.

  • 📏len(df)df.shape로 경계 미리 확인
  • 🧠슬라이싱은 안전, 개별 접근은 위험 — 필요 시 try-except 활용
  • ⚙️루프 내 인덱싱 시 항상 종료 조건 재확인

IndexError는 대부분 “단순 부주의”에서 비롯됩니다.
그러나 사전에 데이터 크기를 점검하고 슬라이싱 중심의 접근으로 바꾸면, 코드의 안정성과 가독성을 동시에 확보할 수 있습니다.



💡 방어적 코딩 패턴과 디버깅 체크리스트

KeyError와 IndexError를 완전히 없애는 것은 어렵지만, 코드를 작성할 때 몇 가지 방어적 코딩 습관을 들이면 예외를 대폭 줄일 수 있습니다.
데이터 구조를 먼저 점검하고, 값 존재 여부를 확인한 뒤 접근하는 습관은 단순한 오류 방지 그 이상으로 코드의 유지보수성과 신뢰도를 높여줍니다.

🧩 존재 여부를 먼저 점검하는 습관

pandas 객체에서 존재 여부를 확인하는 가장 빠른 방법은 in 연산자입니다.
컬럼명이나 인덱스가 존재하는지 먼저 체크한 뒤 접근하면 KeyError를 예방할 수 있습니다.

CODE BLOCK
# KeyError 방지
if "pop" in df.columns:
    print(df["pop"].mean())
else:
    print("⚠️ 'pop' 컬럼이 존재하지 않습니다.")

# IndexError 방지
if len(df) > 2:
    print(df.iloc[2])
else:
    print("⚠️ 행 인덱스가 범위를 벗어납니다.")

🔍 디버깅 체크리스트

KeyError나 IndexError가 발생했을 때는 감으로 수정하지 말고, 아래 체크리스트를 순서대로 점검하세요.
대부분의 경우 원인은 이 다섯 가지 중 하나에 있습니다.

  • 🔎df.columns / df.index를 출력해 실제 이름 확인
  • 🧩대소문자, 공백, 특수문자 포함 여부 확인
  • ⚙️선택기가 loc/iloc인지, at/iat인지 구분
  • 📏len(df)와 df.shape로 데이터 크기 점검
  • 🧰try-except로 예외 처리 적용

🧾 유지보수를 위한 코드 패턴

데이터 구조가 자주 바뀌는 환경에서는 하드코딩 대신 조건부 접근get() 메서드를 사용하는 것이 좋습니다.
특히 Series.get()dict.get() 방식은 존재하지 않는 키에도 안전하게 접근할 수 있습니다.

CODE BLOCK
# get()을 활용한 방어적 접근
s = df["pop"] if "pop" in df else pd.Series()

value = s.get(1, default=0)   # IndexError 없이 기본값 반환

💎 핵심 포인트:
데이터의 불확실성을 완전히 없앨 수는 없습니다.
하지만 방어적 코딩과 예외 처리를 조합하면, KeyError와 IndexError는 치명적 장애가 아닌 단순 로그 수준으로 격하시킬 수 있습니다.

결국 중요한 것은 “예외를 피하는 코드”가 아니라 “예외를 예측한 코드”입니다.
모든 데이터는 변할 수 있다는 전제 아래, 확인하고, 대비하고, 처리하는 습관을 갖춘다면 pandas의 오류는 더 이상 불안 요소가 되지 않습니다.

자주 묻는 질문 (FAQ)

KeyError와 IndexError의 차이를 간단히 구분하는 법은?
KeyError는 존재하지 않는 레이블(label) 접근, IndexError는 범위를 벗어난 정수 위치(position) 접근입니다.
즉, locat은 KeyError, ilociat은 IndexError와 연결됩니다.
KeyError가 발생했을 때 가장 먼저 확인할 것은?
가장 먼저 df.columns 또는 df.index를 출력해 실제 이름을 확인해야 합니다.
대소문자, 공백, 인코딩 차이로 인해 이름이 미묘하게 달라질 수 있습니다.
iloc에서 인덱스 초과가 발생했을 때 해결 방법은?
len(df) 또는 df.shape를 사용해 데이터 크기를 먼저 확인하세요.
인덱스는 0부터 시작하므로, 최대 인덱스는 항상 len(df)-1입니다.
컬럼명이 다를 때 자동으로 맞춰주는 방법이 있을까요?
완전 자동은 어렵지만, df.columns = df.columns.str.strip().str.lower() 같은 전처리로 기본적인 정규화를 할 수 있습니다.
이 과정을 통해 공백이나 대소문자 차이로 인한 KeyError를 줄일 수 있습니다.
try-except로 KeyError를 처리하면 안 좋은가요?
아닙니다. 오히려 안정적인 코드에서는 필수적입니다.
다만 반복적으로 발생하는 경우에는 데이터 구조 자체를 수정하거나 컬럼 검증 로직을 추가하는 편이 좋습니다.
KeyError가 발생하지 않게 값을 가져오는 다른 방법이 있나요?
get() 메서드를 사용하는 것이 좋습니다.
예를 들어 df.get("col", default=pd.Series())처럼 기본값을 지정하면 KeyError 없이 안전하게 접근할 수 있습니다.
IndexError가 발생하지 않도록 루프를 짜려면?
루프 범위를 항상 range(len(df))로 설정하면 안전합니다.
길이가 바뀌더라도 자동으로 범위가 조정되어 IndexError를 예방할 수 있습니다.
KeyError와 IndexError 외에 비슷한 예외가 있나요?
있습니다. 예를 들어 ValueError는 잘못된 인자 전달 시,
TypeError는 연산 불가능한 타입 조합일 때 발생합니다.
KeyError와 IndexError는 인덱싱 단계의 문제라는 점에서 이들과 구분됩니다.

🧭 pandas 인덱싱 오류를 피하는 현실적인 노하우

pandas에서 발생하는 KeyErrorIndexError는 코드 실수라기보다, 데이터 구조의 불확실성을 잘 보여주는 신호입니다.
이 두 오류의 본질은 ‘존재하지 않는 것에 접근’하려는 시도로, 원인을 정확히 이해하고 미리 대비하면 전혀 두려울 필요가 없습니다.
레이블 기반의 loc/at과 위치 기반의 iloc/iat을 명확히 구분하고, 사전 점검과 예외 처리를 함께 적용하면 pandas 인덱싱은 안정적이고 예측 가능한 코드로 변합니다.

또한 KeyError를 줄이기 위한 컬럼 정규화(df.columns.str.strip().str.lower())와 IndexError 예방을 위한 범위 검증(len(df), df.shape)은 단순하지만 효과적인 습관입니다.
데이터 수집부터 분석까지의 전 과정에서 이런 점검 루틴을 자동화하면, 한 번의 실수로 전체 파이프라인이 멈추는 상황을 미리 방지할 수 있습니다.

결국 pandas에서 중요한 것은 “예외가 없을 코드”가 아니라 “예외를 감당할 준비된 코드”입니다.
KeyError와 IndexError를 단순히 피하려 하지 말고, 디버깅과 예방까지 염두에 둔 구조적 코딩 습관을 통해 데이터 처리의 안정성을 확보하세요.
이 글이 pandas를 다루는 여러분의 디버깅 시간을 단축하는 작은 도움이 되길 바랍니다.


🏷️ 관련 태그 : pandas, KeyError, IndexError, 데이터분석오류, 파이썬예외처리, 데이터인덱싱, loc, iloc, 예외디버깅, 파이썬기초, pandas오류해결