F1 레이스에서 이런 상황을 상상해보자. 피트월에 수백 개의 센서 데이터가 실시간으로 쌓인다. 엔지니어는 그 중에서 특정 랩, 특정 구간, 특정 타이어 온도 데이터만 골라내야 한다. 전체 데이터를 처음부터 끝까지 훑을 시간이 없다. 정확한 위치를 알고, 바로 꺼내야 한다.
오늘날 pandas 코드는 AI에게 맡길 수 있다. 하지만 AI에게 “원하는 데이터를 꺼내줘”라고 말하는 것과 “날짜 인덱스 기준으로 3일부터 5일, A와 C 컬럼만 필터링해줘”라고 말하는 것은 결과가 완전히 다르다. pandas 인덱싱 개념을 아는 사람만이 AI에게 정확하게 요청할 수 있다. 이 글은 코드 작성이 아니라, 정확한 요청을 위한 개념 이해를 목적으로 한다.
loc과 iloc — 어떤 기준으로 데이터를 가리키는가
pandas에서 데이터를 꺼낼 때 가장 먼저 결정해야 할 것이 있다. 인덱스를 이름으로 부를 것인가, 번호로 부를 것인가.
| 구분 | 기준 | 끝값 포함 여부 |
|---|---|---|
loc | 레이블(인덱스 이름) 기반 | 끝값 포함 |
iloc | 정수 위치 기반 | 끝값 미포함 |
예를 들어 인덱스가 날짜(2025-01-01, 2025-01-02 …)로 되어 있다면 loc이 자연스럽다. 반면 인덱스가 무엇인지 관계없이 “위에서 세 번째 행”처럼 순서로 접근하고 싶다면 iloc을 써야 한다.
끝값 처리가 두 방식의 가장 큰 차이다. loc은 끝값을 포함하고, iloc은 포함하지 않는다. AI에게 요청할 때 이 차이를 명확히 전달하지 않으면 원하는 범위와 다른 결과가 나올 수 있다.
# loc — 날짜 레이블 기반, 3일과 4일 모두 포함
df.loc['2025-01-03':'2025-01-04', 'A':'B']
# iloc — 정수 위치 기반, 3번과 4번 위치 (끝값 5 미포함)
df.iloc[3:5, 0:2]
💬 AI 프롬프트 예시 “pandas 데이터프레임 df가 있어. 인덱스는 날짜 형식이야. 2025-01-03부터 2025-01-04까지의 행에서 A 컬럼과 B 컬럼만 loc으로 가져오는 코드 작성해줘.”
범위 접근 — 연속과 비연속, 무엇이 다른가
데이터를 꺼낼 때 범위가 연속적인지 아닌지에 따라 접근 방식이 달라진다.
연속 범위는 슬라이싱으로 표현한다. 시작과 끝을 콜론으로 이어 쓴다. 이때 행과 열 모두 명시적으로 적는 것이 실수를 줄인다. 열 부분을 생략하면 의도와 다르게 동작하는 경우가 있기 때문이다.
비연속 범위는 리스트로 표현한다. 2번, 4번, 7번 행처럼 띄엄띄엄 있는 데이터를 한 번에 가져오려면 대괄호 안에 리스트를 넣는다. 연속이 아니어도 된다는 점이 핵심이다.
특정 컬럼 전체, 또는 특정 행 전체를 가져올 때는 해당 축에 콜론(:)만 입력한다. “모든 행에서 B, C 컬럼만”이라면 행 자리에 :, 열 자리에 범위를 지정하면 된다.
💬 AI 프롬프트 예시 “df에서 0-indexed 기준으로 1번째, 3번째, 5번째 행의 A 컬럼과 C 컬럼만 iloc으로 가져오는 코드 작성해줘. 비연속 선택이야.”
단일 값 접근 — at과 iat을 써야 할 때
하나의 셀에만 접근할 때는 at과 iat을 쓴다. loc과 iloc의 단일 값 전용 버전이다.
| 구분 | 기준 | 특징 |
|---|---|---|
at | 레이블 기반 | loc 대응, 단일 값 전용 |
iat | 정수 위치 기반 | iloc 대응, 단일 값 전용 |
loc보다 at이, iloc보다 iat이 처리 속도가 빠르다. 반복 연산이 많은 코드에서 체감 차이가 생긴다. 다만 범위 접근이나 다중 선택에는 쓸 수 없다. 딱 하나의 값을 읽거나 수정할 때만 사용한다.
AI에게 요청할 때 “특정 셀 하나만”이라는 조건을 명시하면 AI가 at/iat을 선택하게 유도할 수 있다.
💬 AI 프롬프트 예시 “df에서 인덱스 ‘2025-01-01’, 컬럼 ‘A’에 해당하는 단일 셀 값을 빠르게 읽는 코드 작성해줘. 단일 값 전용 메서드를 써줘.”
불리언 필터링 — 조건으로 데이터를 추려내는 법
숫자 위치나 레이블이 아닌, 조건으로 데이터를 골라내는 방식이다. 현장 데이터 분석에서 가장 자주 쓰이는 패턴이기도 하다.
기본 구조는 단순하다. 조건식을 대괄호 안에 넣으면 그 조건을 만족하는 행만 반환된다. 조건을 만족하지 않으면 해당 셀은 NaN으로 채워지거나, 행 자체가 제외된다.
특정 값 목록에 해당하는 행만 추리고 싶을 때는 isin()을 쓴다. 비교 연산자로 표현하기 어려운 목록 조건에 적합하다. 예를 들어 장비 코드가 여러 개일 때 한 번에 지정할 수 있다.
조건 필터링은 어떤 기준으로 데이터를 추려야 하는지를 아는 사람이 AI에게 정확히 전달할 수 있다. 조건 자체는 현장 지식에서 나온다.
💬 AI 프롬프트 예시 “df에서 ‘equipment’ 컬럼 값이 ‘PUMP_A’ 또는 ‘PUMP_B’인 행만 필터링하는 코드 작성해줘. isin()을 써줘.”
데이터 수정과 삭제 — 원본이 바뀌는 조건을 알아야 한다
pandas에서 수정과 삭제가 헷갈리는 이유는 코드를 실행해도 원본이 바뀌지 않는 경우가 많기 때문이다. 언제 원본이 바뀌고, 언제 바뀌지 않는지를 구분하는 것이 핵심이다.
값 수정은 loc 또는 iloc으로 접근한 뒤 값을 할당(=)하면 원본이 바뀐다. 컬럼 추가는 새 컬럼명으로 직접 할당하면 된다. 기존 컬럼을 연산한 결과를 새 컬럼으로 붙이는 방식이 가장 흔하다.
조건부 값 변환에는 where와 np.where가 쓰인다. 둘의 차이는 조건을 만족할 때와 만족하지 않을 때 각각 어떤 값을 적용하느냐에 있다.
| 구분 | 조건 만족 시 | 조건 불만족 시 |
|---|---|---|
df.where(조건, 대체값) | 원래 값 유지 | 대체값으로 치환 |
np.where(조건, A, B) | A 적용 | B 적용 |
행/컬럼 삭제는 drop()을 쓰는데, 가장 많이 실수하는 부분이 여기에 있다. drop()은 기본적으로 원본을 건드리지 않는다. 결과를 실제로 반영하려면 두 가지 방법 중 하나를 선택해야 한다.
# 방법 1 — inplace=True로 원본 직접 수정
df.drop(columns='A', inplace=True)
# 방법 2 — 결과를 새 변수에 담기 (원본 보존)
df_new = df.drop(columns='A')
원본을 유지하면서 작업하고 싶다면 방법 2가 안전하다.
💬 AI 프롬프트 예시 “df에서 ‘A’ 컬럼을 삭제하되, 원본 df는 유지하고 결과를 df_new에 담는 코드 작성해줘.”
핵심 요약
pandas 인덱싱의 각 방법은 “어떤 기준으로, 어떤 범위를, 어떤 목적으로” 접근하느냐에 따라 선택이 달라진다.
| 상황 | 방법 | AI 요청 핵심 키워드 |
|---|---|---|
| 레이블로 범위 접근 | loc | “인덱스 이름 기준으로” |
| 정수 위치로 범위 접근 | iloc | “0-indexed 위치 기준으로” |
| 단일 셀 접근 | at / iat | “단일 값 전용 메서드로” |
| 조건으로 행 필터링 | 불리언 인덱싱, isin() | “조건을 만족하는 행만” |
| 조건부 값 치환 | where(), np.where() | “조건 만족/불만족 각각 다른 값으로” |
| 행/컬럼 삭제 | drop() | “원본 유지 여부 명시” |
코드를 외울 필요는 없다. 하지만 어떤 개념을 쓰는지, 그 개념의 판단 기준이 무엇인지를 알아야 AI에게 정확한 결과를 요청할 수 있다. 개념이 요청의 정밀도를 결정한다.
[링크 제안]
pandas 인덱싱 개념을 잡았다면, AI에게 데이터 조작을 요청하는 실전 흐름을 바로 확인할 수 있다. Django DB 연동 과정에서 AI 프롬프트로 작업을 요청한 구조와 전략이 실제로 어떻게 구성되는지 참고가 된다. → Django DB 연동, 하드코딩에서 데이터베이스로 전환하는 구조와 프롬프트 전략 3가지
AI에게 정확하게 요청하는 능력은 개념 이해에서 끝나지 않는다. 설계 먼저·범위 선언·단계별 검증 — AI와 함께 개발할 때 잘 쓰는 사람이 지키는 원칙이 따로 있다. → AI 개발 설계, 잘 쓰는 사람은 이렇게 다르다 — 바이브 코딩 5가지 핵심 원칙
pandas 공식 문서에서 인덱싱 전체 레퍼런스를 확인할 수 있다: pandas 공식 문서 — Indexing and Selecting Data







