1. .loc와 .iloc의 차이점
구분.loc[].iloc[] | ||
약자 | .loc = location | .iloc = integer location |
기반 | 라벨(Label) 기반 | 정수(Integer) 기반 |
행 선택 | df.loc['a'] → 'a' 인덱스의 행 | df.iloc[0] → 첫 번째(0번째) 행 |
열 선택 | df.loc[:, 'A'] → 'A' 열 선택 | df.iloc[:, 0] → 첫 번째(0번째) 열 선택 |
범위 선택 | df.loc['a':'c'] → 'a'~'c' 포함 | df.iloc[0:2] → 0~1 (마지막 포함 X) |
2. ()이 아니라 []를 사용하는 이유
.loc는 함수(메서드)가 아니라 호출할 수 없는 속성(attribute)이기 때문
"호출할 수 없는 속성(attribute) 객체란?"
👉 Python에서 "호출할 수 있다"는 건 ()를 붙여 실행할 수 있다는 뜻이야!
👉 "호출할 수 없는 속성"은 ()를 붙여 실행할 수 없는 객체를 말해!
🔹 df.loc는 _LocIndexer라는 속성(attribute) 객체이고, 함수가 아니다!
🔹 따라서 df.loc()처럼 ()를 붙이면 "호출할 수 없는 객체"라는 오류가 발생
Python에서 호출(callable) 가능한 객체는 다음과 같아
- 함수 (def)
def my_func(): return "Hi!" print(my_func()) # ✅ 호출 가능
- 클래스 (생성자 호출)
def my_func(): return "Hi!" print(my_func()) # ✅ 호출 가능
- 람다 함수 (lambda)
add = lambda x, y: x + y print(add(2, 3)) # ✅ 5
df.loc는 _LocIndexer라는 속성(attribute) 객체이고, 함수가 아니다!
📌 _LocIndexer의 역할
- .loc[]가 동작할 수 있도록 도와줌
print(df.loc['b']) # ✅ 'b' 인덱스의 데이터 가져오기
- 인덱스 + 컬럼 동시 선택 가능
print(df.loc['b', 'A']) # ✅ 'b' 행의 'A' 열 값 (20)
- 조건 필터링도 가능
print(df.loc[df['A'] > 15]) # ✅ A 값이 15 초과인 행 선택
_LocIndexer는 불리언 조건을 해석하여 원하는 행을 필터링해 줌.
📌 _LocIndexer가 _getitem_()을 활용하는 방식
- df.loc['a']처럼 .loc[]을 사용할 때 내부적으로 _getitem_()이 실행됨.
- _getitem_()은 "어떤 데이터를 가져올지" 판단하는 Pandas의 핵심 메서드 중 하나야.
print(df.loc['a']) # 내부적으로 _LocIndexer.__getitem__('a') 실행
👉 _LocIndexer가 .loc[]로 들어오는 값을 분석해서 적절한 데이터를 반환하는 거야!
"df.loc['a']에서 _LocIndexer가 _getitem_()을 활용하는 절차"
Pandas에서 df.loc['a']가 실행될 때 내부적으로 _LocIndexer 객체가 _getitem_()을 호출하여 데이터를 찾는 과정을 거쳐!
아래 절차를 보면 어떻게 동작하는지 이해하기 쉬울 거야.
📌 1️⃣ df.loc['a'] 실행
import pandas as pd
df = pd.DataFrame({'A': [10, 20, 30]}, index=['a', 'b', 'c'])
print(df.loc['a']) # 'a' 인덱스의 데이터 가져오기
이 코드가 실행될 때 내부적으로 다음과 같은 과정이 진행됨!
📌 2️⃣ df.loc가 _LocIndexer 객체 반환
print(type(df.loc))
# ✅ <class 'pandas.core.indexing._LocIndexer'>
- df.loc는 _LocIndexer 객체를 반환함.
- 즉, df.loc['a']를 실행하면 실제로 _LocIndexer.__getitem__('a')이 호출됨.
📌 3️⃣ _LocIndexer.__getitem__('a') 실행 과정
result = df.loc.__getitem__('a') # 내부적으로 실행됨
print(result)
출력:
A 10
Name: a, dtype: int64
- _LocIndexer.__getitem__('a')는 'a'라는 인덱스를 찾고 해당 행을 반환함.
- 내부적으로 Pandas의 인덱스 매핑을 활용하여 'a' 인덱스에 해당하는 데이터를 검색함.
📌 4️⃣ _getitem_() 내부 동작 절차
- 입력값 'a'가 문자열인지 확인
if isinstance(key, str): # 'a'는 문자열이므로 True
- DataFrame의 인덱스에서 'a'를 검색
row_index = df.index.get_loc('a') # 'a'의 위치를 찾음 (0번째 위치)
- 해당 행 데이터를 반환
return df.iloc[row_index]
- df.iloc[0]과 동일한 동작을 수행하여 해당 행의 데이터를 반환함.
📌 5️⃣ 최종 반환 결과
A 10 Name: a, dtype: int64
- _LocIndexer.__getitem__('a')가 실행되면서 df.iloc[0]과 동일한 방식으로 데이터가 반환됨!
✅ 결론!
✔ df.loc['a'] 실행 → _LocIndexer.__getitem__('a') 호출
✔ _getitem_()은 인덱스에서 'a'를 찾고 해당 행을 반환
✔ 결과적으로 df.iloc[0]과 비슷한 동작을 하지만, .loc[]는 "라벨 기반", .iloc[]는 "숫자 기반" 접근 방식
🚀 즉, .loc['a']는 내부적으로 _getitem_()을 호출하여 해당 행을 찾아 반환하는 구조야!
반응형
'ChatGPT 아카이브 > Pandas' 카테고리의 다른 글
drop_duplicates() 함수 파헤치기 (0) | 2025.03.04 |
---|---|
표현식(expression)과 할당문(statement) 둘 다 함수 return 값에 올 수 있을까? + 할당표현식( := ) (0) | 2025.03.04 |
왜 Pandas는 2차원 리스트를 기본으로 사용할까? (0) | 2025.03.03 |
데이터프레임이 SQL보다 빠를까? (0) | 2025.03.03 |
SQL 테이블 vs DataFrame 비교 (0) | 2025.03.03 |