
Pandas의 Indexer란?
Indexer(인덱서)는
- "값(value) 그 자체를 조건으로 삼아 접근하거나 필터링하는 방식"과는 달리,
- 라벨(label)이나 정수 위치(index 번호)를 기반으로 해석하여 데이터를 선택하거나 필터링하는 도구임.
다시 말해, DataFrame/Series에 부착된 indexing에 사용되는 일종의 accessor로,
라벨(label)이나 정수 위치(index 번호)를 해석해 데이터를 선택하거나 필터링하는 데 사용(indexing)된다.
- 주요 역할: 사용자가 지정한 키(key)를 어떤 규칙(라벨 기반 또는 위치 기반)으로 해석할지 결정.
- 종류:
loc,iloc,at,iat등이 있으며, 각각 라벨 기반/위치 기반, 단일/다중 접근 용도로 나뉨.
Pandas의 공식 문서 기준으로 정리하면:
- Indexer는 인덱싱 동작에 사용되는 accessor로,
loc,iloc,at,iat등이 해당. - Pandas에서 애기하는 Accessor는 특정 dtype 전용 메서드를 제공하는 인터페이스로,
.str,.dt,.cat등이 있음.
따라서 Indexer는 넓은 의미에서 accessor의 한 종류이지만, pandas 문서에서는 인덱싱 인터페이스로 따로 구분하고 있음.
0. 기본 준비
다음 코드는 실습에 사용할 간단한 DataFrame을 생성함.
이후의 예제들은 모두 이 DataFrame을 기반으로 동작함.
import pandas as pd
# (예제 공통) 테스트용 DataFrame 생성
df = pd.DataFrame(
{
"name": ["A", "B", "C", "D"], # column 라벨 'name'
"score": [10, 20, 30, 40], # column 라벨 'score'
"grp": ["x", "x", "y", "y"], # column 라벨 'grp'
}
)
# 별도의 인덱스를 주지 않았으므로 df.index에는 RangeIndex 객체가 자동 부여됨 (0,1,2,3)

1. Index와 Indexer
Pandas의 indexer인 loc, iloc, at, iat 를 이해하기 위해 필요한 기본 개념들은 다음과 같음:
1-1. Index (인덱스)
DataFrame/Series의 axis(축)에 붙은 라벨들의 집합을 표현하는 클래스(Index 및 그 서브클래스).
이 클래스는 DataFrame의 row와 column을 구분하기 위해 사용되는 라벨 시스템을 제공한다.
Pandas에서 Index클래스 객체의 예를 들면,
df.index는 row 라벨들의 Index 객체 이며,df.columns는 column 라벨들의 Index 객체 임.
Index클래스의 요소인 label은 중복 허용 임: 같은 라벨이 Index 내에서 여러 번 등장할 수 있으며, 반드시 고유할 필요는 없음.
- 대표적인 Index 서브클래스 (모두 Index 슈퍼클래스를 상속):
RangeIndex: 0..n-1 등 단조 증가 정수일 때 자동 생성되는 특수 인덱스(메모리 효율)Int64Index: 임의의 정수 라벨Float64Index: 실수 라벨Index(object): 문자열 등 일반 객체 라벨 (별도의 서브클래스가 아니라 기본 Index 클래스의 인스턴스)DatetimeIndex: 시계열 라벨CategoricalIndex: 범주형 라벨MultiIndex: 계층적 라벨
type(df.index) # pandas.core.indexes.range.RangeIndex
# (명시적 index 지정하지 않은 경우, 기본index)
df2 = df.set_index("name") # 'name' column을 row 인덱스로 사용
type(df2.index) # pandas.core.indexes.base.Index
# (dtype=object; 문자열 라벨)
1-2. Label (라벨)
라벨(Label) 은 DataFrame/Series의 각 축(Columns, Index)에 붙은 개별 이름값을 의미함.
- 정수, 문자열, 날짜 등 해시 가능한 값이어야 Label로 사용 가능: Immutable and Hashable.
- row와 column을 구분하고 접근할 때 사용됨.
- 단, 중복을 허용함.
2024.05.21 - [개발환경] - [CE] Hash Algorithm
[CE] Hash Algorithm
Hash란?Hash 는 임의의 크기를 가진 데이터를 고정된 크기의 (고유한) 데이터로 변환하는 방법 임.이 변환 과정은 Hash Algorithm에 의해 명확하게 정의됨.Hash Algorithm을 통해 생성된 해시 값(Hash, Hash Valu
ds31x.tistory.com
1-3. Indexer (인덱서)
DataFrame/Series에 부착된 indexing을 위한 특수한 접근자 객체.
[]안에 들어온 키(key) 를- row/column 선택 연산으로 변환 한다.
종류는 다음과 같음:
loc: 라벨(label) 기반 multi-axis(다축) 선택 (슬라이스 끝 포함)iloc: 정수 위치(position) 기반 multi-axis(다축) 선택 (슬라이스 끝 제외)at: 라벨 기반 단일 스칼라 최적화(읽기/쓰기)iat: 위치 기반 단일 스칼라 최적화(읽기/쓰기)
각각의 클래스는 다음과 같음:
print(type(df.loc)) # <pandas.core.indexing._LocIndexer> object
print(type(df.iloc)) # <pandas.core.indexing._iLocIndexer> object
1-4. df[...] (__getitem__()) : Column에 접근 및 추출
위 제목에서 [...]는 square brackets 를 이용하는 indexing key를 의미함.
df['col']은 DataFrame 객체의__getitem__()이 구현한 “column 선택”임: Indexer가 아님.df.loc[...]/df.iloc[...]는 Indexer 객체의__getitem__()special method가 동작함.
아래의 5번 항목을 참고.
주의할 점은 Indexer에선 row에 대한 지정이 요구된다는 점임.
2. loc — 라벨(label) 기반 인덱서
loc은
기존 데이터의 수정 및 편집,
새로운 레코드(행) 추가가 가능하다.
- 라벨(label): 인덱스/column 축에 붙은 이름값(정수/문자열/날짜 등).
df.index에 기본 할당된 RangeIndex의 0,1,2,…도 라벨 임!
- 주의할 점은 slicing에서 끝 라벨 포함(inclusive).
주요 용도:
- label을 기반으로 특정 row나 column에 접근하거나,
- label을 기반으로 조건에 맞는 row들을 필터링.
- 새로운 레코드 추가 가능: 새로운 라벨에 값을 할당하면 존재하지 않던 row가 추가됨.
딱히 다른 label을 사용하도록 특정 column을 index로 지정하거나, 생성시 index를 따로 지정하지 않은 경우 RangeIndex가 index임.
이 경우, 새로운 record(or row) 의 추가는 다음과 같이 len()함수를 이용하면 됨.
복수 개의 row를 추가하는 경우는 concat() 함수 또는 메서드 를 사용한다.
다음은 맨 끝의 row를 복제하여 새로운 row로 추가하는 코드임:
df.loc[len(df)] = df.iloc[-1].copy() # 권장.
df.loc[len(df)] = df.iloc[-1] # 일반적으로 사용가능하나,
# SettingWithCopyWarning이 발생할 수도 있음.
2-1. 사용 패턴
# 단일 row·단일 column (라벨 기반)
df.loc[1, "score"] # 라벨 1 row의 'score' 값 → 20

# 단일 row·다중 column (column 라벨 리스트)
df.loc[2, ["name", "grp"]] # 라벨 2 row의 'name','grp' column 선택

# 다중 row·다중 column (row/column 라벨 리스트)
df.loc[[1, 3], ["name", "score"]] # 라벨 1,3 row의 'name','score' column 선택

# 라벨 slicing (끝 포함)
df.loc[1:2, "name":"grp"] # 라벨 1~2 row × 'name'~'grp' column 선택

# boolean mask or boolean indexing
mask = df["score"] >= 20 # masks는 Series객체임.
df.loc[mask, ["name", "score"]] # 'score'>=20 조건 만족 row × 'name','score' column 선택

loc은 라벨기반 인덱서이기 때문에 boolean mask는 boolean 값들을 가지는 Series객체로 처리됨.
주의:
- 복수의 조건을 사용시 and가 아닌 bitwise연산자(Series객체의 bit는 element가 됨)로
&,|를 사용해야함: df[(df["grp"]=="x")& (df["score"]>20)]
# boolean mask 는 보통 row 선택에 많이 쓰이지만,
# column 선택에도 boolean mask를 지정해 활용할 수 있다.
col_mask = [True, False, True] # 'name'과 'grp'만 선택. ndarray나 list객체도 boolean mask가능.
df.loc[:, col_mask] # 특정 column 선택 (column 마스크)

# 새로운 row 추가
df.loc[4] = ["E", 50, "z"] # 라벨 4가 없으므로 새로운 row 추가
df

2-2. 값 할당
# 단일 값 쓰기
df.loc[1, "score"] = 25 # 라벨 1 row의 'score'를 25로 수정

# 조건부 쓰기
df.loc[df["grp"] == "y", "score"] += 100 # 'grp'가 y인 row들의 'score' 값에 100 더하기

# 새 column 추가
df.loc[:, "passed"] = df["score"] >= 30 # 'score'>=30 여부를 새로운 column 'passed'로 추가

2-5. 중복 라벨
g = df.set_index("grp")
g.loc["x"] # 라벨 'x'인 모든 row 반환 (2행: name=A,B)

가능하지만, 가급적 중복 라벨은 권하지 않음.
3. iloc — 위치(position) 기반 인덱서
iloc은
기존 데이터의 수정 및 편집이 가능하나,
새로운 row 추가는 불가.
- row/column의 0부터 시작하는 정수 위치(position)를 사용.
loc에서 사용하는 인덱스 라벨과 무관.
- slicing에서 끝 제외 모드임(exclusive로 python의 slicing과 동일).
주요 용도:
- 정수 위치(integer position)를 기반으로 특정 row나 column에 접근하거나,
- 정수 위치를 기반으로 조건에 맞는 row들을 필터링하는 데 사용됨.
- 존재하지 않는 위치에는 접근할 수 없어 새로운 row 추가는 불가능: loc과의 가장 큰 차이점 중 하나임.
3-1. 사용 패턴
# 단일 위치
df.iloc[1, 1] # row 위치 1 × column 위치 1

# 위치 슬라이스
df.iloc[0:2, 0:2] # row 위치 0,1 × column 위치 0,1 → 부분 DataFrame(name,score)

# boolean mask (numpy ndarray)
mask = (df["score"] >= 20).values
df.iloc[mask, [0, 1]] # 'score'>=20 조건 만족 row × column 위치 0,1(name,score)
3-2. 값 할당
df.iloc[1, 1] = 26 # row 위치 1, column 위치 1의 값을 26으로 수정

iloc은
새로운 row 추가는 불가하지만,
기존 데이터의 편집은 가능하다.
3-3. 새로운 row 추가 불가
df.iloc[2] = ["C", 30, "z"] # 존재하지 않는 위치 2 → IndexError 발생

4. at / iat — 단일 스칼라 값 접근에 최적화
at/iat역시
기존 데이터의 수정 및 편집에 사용가능.
단일 원소에 대한 잦은 접근/수정은 at/iat가 대체로 loc/iloc보다 빠르다.
(하지만 많이 이용되는 편은 아님.)
주요 용도:
- 단일 스칼라 원소에 빠르게 접근하거나 수정할 때 사용된다.
- 반드시 존재하는 라벨(
at)이나 위치(iat)에 대해서만 동작한다.
# at: 라벨 기반 단일 원소
df.at[1, "score"] # 라벨 1 row의 'score' 읽기
df.at[1, "score"] = 27 # 라벨 1 row의 'score'를 27로 수정
# iat: 위치 기반 단일 원소
df.iat[0, 1] # row 위치 0, column 위치 1의 값 읽기
df.iat[0, 1] = 11 # row 위치 0, column 위치 1의 값을 11로 수정
5. df[...] — column 선택 (getitem())
DataFrame객체에서 [...]은 column 선택 및 추출에 사용된다. 주의할 것.
df["col"]: 단일 column 선택 → Series 반환df[["c1", "c2"]]: 여러 column 선택 → DataFrame 반환df[mask]:mask는 row와 길이가 같은 boolean mask로 row 필터링에 사용됨.
df["name"] # 'name' column만 Series로 반환

df[["name", "score"]] # 'name','score' column을 DataFrame으로 반환

df[df["score"]>=20] # 'score'>=20 조건 만족 row 필터링 **

row 선택에 일반
[...]는 권장하지 않음.
단, boolean mask의 경우 예외임.
주로 column 선택임을 기억할 것.
6. RangeIndex와 set_index/reset_index
RangeIndex: DataFrame 생성 시 자동 부여되는 특수 인덱스 객체의 클래스.
- 단, 명시적으로 특정 column을 인덱스(=
df.index)로 지정하면 RangeIndex는 사라지고 dtype에 맞는 Index로 교체.set_index(column_label_str): 인자로 주어진 column name(or label)을df.index로 지정.
reset_index(): 현재 인덱스를 일반 column으로 되돌리거나(default) 또는 삭제(drop=True 로 argument넘긴 경우)하고, 새 RangeIndex를 부여.
df.index # RangeIndex(start=0, stop=4, step=1)

df2 = df.set_index("score") # 'score' column을 인덱스로 지정
type(df2.index) # Int64Index (정수 인덱스)


# reset_index() 사용 예
df3 = df2.reset_index() # 'score'가 다시 일반 column으로 이동하고 RangeIndex 부여
df3.head() # 확인용 미리보기

2023.09.20 - [Python/pandas] - [Pandas] Index 지정 관련 메서드 : reset_index, set_index
[Pandas] Index 지정 관련 메서드 : reset_index, set_index
DataFrame 인스턴스에서 index를 새로 만들거나 다른 columns 를 index로 지정하는데 사용된다.reset_indexDataFrame 인스턴스에서 기존 index 대신하는 새로운 index를 만든다.drop 파라메터의 값을True로 지정한
ds31x.tistory.com
7. 삭제 (row/column)
인덱서를 직접 사용해 삭제하는 기능은 없음.
drop() 메서드를 사용해 라벨을 기준으로 row/column을 삭제하는 방법이 일반적임
대신 인덱서의 경우,
특정 조건이나 슬라이싱을 통해 원하는 row/column을 선택한 후,
그 결과를 다시 df에 덮어쓰는 방식으로 사실상 삭제 효과를 낼 수 있음.
# 조건 기반으로 특정 row 삭제 효과 (score < 20 인 row 제거)
df = df.loc[df["score"] >= 20]
df

# iloc을 이용한 row 삭제 효과 (첫 번째 row 제거)
df = df.iloc[1:]
df

다음은 drop() 메서드를 사용하는 예임:
# 조건 기반으로 특정 row 삭제 효과 (score < 20 인 row 제거)
df = df.loc[df["score"] >= 20]
# iloc을 이용한 row 삭제 효과 (첫 번째 row 제거)
df = df.iloc[1:]
# drop() 메서드를 이용한 row 삭제
df = df.drop(1, axis=0) # 라벨 1 row 삭제
# drop() 메서드를 이용한 column 삭제
df = df.drop("score", axis=1) # 'score' column 삭제
2024.01.09 - [Python/pandas] - [pandas] Column (or rows) 제거하기
[pandas] Column (or rows) 제거하기
DataFrame 에서 column을 제거하는데에 사용되는 idiomatic approach는 drop 메서드를 사용하는 것임. 사실 drop은 axis라는 parameter를 가지고 있고,0이 주어지면 row를 지우고,1이 주어지면 column을 지움.첫번째
ds31x.tistory.com
8. loc/iloc/at/iat 패턴 정리
- 단일 원소
loc[r, c],iloc[i, j]- 최적화:
at[r, c],iat[i, j]
- 다중 원소(리스트)
- 라벨:
df.loc[[r1, r2], [c1, c2]] - 위치:
df.iloc[[i1, i2], [j1, j2]]
- 라벨:
- slicing
loc[r1:r2, c1:c2](끝 포함, inclusive)iloc[i1:i2, j1:j2](끝 제외, exclusive)
- boolean mask
df.loc[mask, cols]df.iloc[mask.values, pos]
- 쓰기(할당)
df.loc[cond, col] = valdf.iloc[i, j] = val
- 중복 라벨의 경우
loc["dup"]는 여러 row 반환 가능iloc은 위치 기반이라 중복 라벨에 상관 없음
9. MultiIndex 예시
MultiIndex는 여러 column을 조합하여 계층적인 인덱스를 구성하는 기능을 가리킴.
- 복잡한 데이터 구조를 표현
- 다차원 인덱싱 을 지원.
df = pd.DataFrame(
{
"name": ["A", "B", "C", "D"], # column 라벨 'name'
"score": [10, 20, 30, 40], # column 라벨 'score'
"grp": ["x", "x", "y", "y"], # column 라벨 'grp'
}
)
h = df.set_index(["grp", "name"]) # 두 column을 계층적 인덱스로 설정
h.loc[("x", "A")] # (grp='x', name='A') row 선택 (라벨 튜플)
h.iloc[0] # 첫 번째 row 선택 (위치)

# 상위 라벨 'y' 전체 선택 (하위는 모두)
h.loc[("y", slice(None)), :]

10. 시각 자료 (ASCII 다이어그램)
+-------------------+
DataFrame | df |
+-------------------+
| |
v v
df.index df.columns
(row 라벨 집합) (column 라벨 집합)
| |
<Index subclass> <Index subclass>
(RangeIndex, ...) (Index, ...)
^
|
set_index(...)로 column을
row 라벨로 승격시키면
해당 dtype에 맞는 Index로 변환
11. 요약
df.index= row 라벨(Index 클래스 인스턴스)df.columns= column 라벨(Index 클래스 인스턴스)loc: 라벨 기반, 슬라이스 끝 포함, 기존 데이터 편집 가능, 새로운 row 추가 가능iloc: 위치 기반, 슬라이스 끝 제외, 기존 데이터 편집 가능, 새로운 row 추가 불가at/iat: 단일 스칼라 최적화(읽기/쓰기), 기존 데이터 편집 가능, 새로운 row/column 추가 불가df[...]: column 선택을 담당하는__getitem__규칙(인덱서 아님). row 선택은 주로 boolean mask 또는loc/iloc사용- 인덱스 라벨 중복 가능:
loc은 여러 row를 반환할 수 있으며,iloc은 위치 기반이라 영향 없음 set_index/reset_index: 라벨 구조 전환과 복구- 삭제: 인덱서를 직접 이용한 삭제는 불가. 조건/슬라이싱 후 재할당 또는
drop()메서드 사용
'Python > pandas' 카테고리의 다른 글
| [Pandas] stack() 과 unstack() (0) | 2025.08.23 |
|---|---|
| [Pandas] 값 변경하기 - replace (0) | 2025.08.22 |
| [Pandas] Reduction 과 Aggregation (0) | 2025.08.21 |
| [Pandas] DataFrame : Basic Attributes and Exploration Methods (0) | 2025.08.21 |
| [Pandas] DataFrame 생성-다른 데이터 타입의 객체로부터 (0) | 2025.08.21 |