C.W.K.
Stream
Lesson 04 of 07 · published

Selection, Filtering, 그리고 .loc / .iloc 함정

~13 min · pandas, indexing, loc, iloc, gotcha

Level 0구경꾼
0 XP0/47 lessons0/11 achievements
0/120 XP to next level120 XP to go0% complete

Pandas 에서 가장 큰 혼동 source 는 원하는 row 와 column 어떻게 고를지. 라이브러리가 세 가지 indexing 스타일을 노출하고, 초보자가 그걸 머릿속에서 섞어서 에러 없이 틀린 답을 만들어. 작동하는 프레임워크 여기.

세 indexer

  • df['col'] — label 로 column 접근. Series 반환.
  • df.loc[row_label, col_label]label 기반 selection. Row 와 column 둘 다 label (또는 boolean mask) 로 주소.
  • df.iloc[row_pos, col_pos]position 기반 selection. Row 와 column 둘 다 정수 position 으로 주소 — NumPy 배열처럼.

.loc 은 label 기반, .iloc 은 position 기반, 머릿속에서 절대 섞지 마. Legacy df.ix 는 사라졌어. Chained indexing 스타일 df[df.col > 0]['other'] = ...SettingWithCopyWarning 의 전형적 source — Pandas 3.0 이 Copy-on-Write 의미 아래 그 나사를 더 죄었어.

Copy-on-Write 시대

Pandas 3.0 이 Copy-on-Write (CoW) 를 default 로. 실제 효과: 부모 DataFrame 을 조용히 mutate 하던 chained 할당이 이제는 copy 를 mutate 하거나 (변경이 사라짐) 명확한 에러 raise. 고치는 방법은 항상 같았어 — 할당 왼쪽에 row 와 column 둘 다 들어간 단일 .loc.

Code

Filter 와 할당의 옳고 그른 방법·python
import pandas as pd

df = pd.DataFrame({
    'order_id':   ['A001', 'A002', 'A003', 'A004'],
    'amount_usd': [120.50,   87.30, 215.00,    9.99],
    'status':     ['shipped', 'pending', 'shipped', 'cancelled'],
})

# Label 기반 row select (boolean mask 도 label index 의 일종)
shipped = df.loc[df['status'] == 'shipped']                       # status 가 'shipped' 인 row
shipped_amounts = df.loc[df['status'] == 'shipped', 'amount_usd'] # amount column 만

# Position 기반 — 첫 2 row, 첫 2 column
topleft = df.iloc[:2, :2]

# WRONG — chained 할당, Pandas 3.0 CoW 아래에서 fail 또는 no-op
# df[df['status'] == 'pending']['amount_usd'] = 0      # ← 이러지 마

# RIGHT — row 와 column 둘 다 주소된 단일 .loc
df.loc[df['status'] == 'pending', 'amount_usd'] = 0

# Boolean mask 결합은 & | (괄호 필수)
big_or_pending = df.loc[(df['amount_usd'] > 100) | (df['status'] == 'pending')]

External links

Exercise

위 예시 DataFrame 만들어. .loc 만 (chained indexing 없이) 써서 status'cancelled' 인 모든 row 의 amount_usd0 으로 설정. 그리고 df.query() 로 amount 가 50 ~ 200 사이인 row 다 가져와.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.