본문으로 건너뛰기
김신건의 로그

[Pandas] Boolean Indexing

· 수정 · 📖 약 1분 · 234자/단어 #python #pandas #selection #filter
Pandas Boolean Indexing, pandas 마스킹, pandas 조건 필터

정의

Boolean IndexingTrue/False 의 Series 를 인덱서로 전달 해 행을 선택하는 패턴. pandas 의 가장 흔한 필터링 방법.

mask = df['age'] > 30      # bool Series
df[mask]                    # True 인 행만
df.loc[mask]                # 동등

기본

python
import pandas as pd
df = pd.DataFrame({
  'name': ['Alice', 'Bob', 'Charlie', 'Dave'],
  'age': [25, 30, 35, 40],
})

mask = df['age'] >= 30
print(mask.tolist())
print(df[mask])
결과
[False, True, True, True]
    name  age
1      Bob   30
2  Charlie   35
3     Dave   40
nameage
1Bob30
2Charlie35
3Dave40

복합 조건

df[(df['age'] > 25) & (df['age'] < 40)]    # AND
df[(df['city'] == 'Seoul') | (df['city'] == 'Busan')]    # OR
df[~(df['city'] == 'Seoul')]               # NOT

IMPORTANT

and / or / not 대신 & / | / ~ 를 써야 한다. Python 키워드는 single boolean 만 처리, pandas 는 array 비교라 비트연산자를 사용. 각 조건은 괄호로 감싼다 (연산자 우선순위 때문).

isin / isna / notna / between

df[df['city'].isin(['Seoul', 'Busan'])]
df[df['age'].notna()]
df[df['age'].isna()]
df[df['age'].between(25, 35)]      # 양쪽 inclusive
df[df['age'].between(25, 35, inclusive='left')]   # [25, 35)

Pandas isin / isna 참고.

행 + 컬럼 동시 필터

df.loc[df['age'] > 30, 'salary']                 # Series
df.loc[df['age'] > 30, ['name', 'salary']]       # DataFrame
df.loc[df['age'] > 30, 'salary'] = df.loc[df['age'] > 30, 'salary'] * 1.1

조건부 갱신 (where / mask)

df['salary'] = df['salary'].where(df['age'] > 30, df['salary'] * 0.9)
# age > 30 이면 그대로, 아니면 * 0.9

df['salary'] = df['salary'].mask(df['age'] < 25, 0)
# age < 25 인 경우 0 으로

.where조건이 True 면 유지, False 면 치환. .mask 는 반대.

numpy.where 패턴

import numpy as np
df['category'] = np.where(df['age'] > 30, 'senior', 'junior')

벡터화된 if-else, 빠르다.

함정

1. and / or 사용

df[df['age'] > 25 and df['age'] < 40]    # ❌ ValueError
df[(df['age'] > 25) & (df['age'] < 40)]  # ✓

2. 괄호 빠뜨림

df[df['a'] > 1 & df['b'] > 2]            # ❌ `1 & df['b']` 가 먼저 평가됨
df[(df['a'] > 1) & (df['b'] > 2)]        # ✓

&> 보다 우선순위가 높아서 사고가 자주 난다.

3. SettingWithCopyWarning

sub = df[df['age'] > 30]
sub['new'] = 1     # ⚠️ Warning
# 해법
sub = df[df['age'] > 30].copy()
sub['new'] = 1

4. NaN 의 boolean 처리

mask = df['age'] > 30
# age 가 NaN 인 행 → mask 도 NaN (Falsy 가 아님!)
# 명시적 처리
mask = (df['age'] > 30) & df['age'].notna()

참고

이 글의 용어 (4개)
[Pandas] .loc / .ilocpandas
정의 - : 라벨 기반 인덱싱 (index/column 이름) - : 정수 위치 기반 인덱싱 (0-based) 이 두 indexer 가 pandas 선택의 표준. 만으로는 헷갈리…
[Pandas] DataFramepandas
정의 은 2차원 레이블 테이블. 각 열이 , 모든 열이 같은 (행 라벨) 를 공유. SQL 테이블 / Excel 시트 / R data.frame 의 Python 대응체. 생성 <…
[Pandas] isin / isna / notnapandas
정의 | 메서드 | 의미 | |:---|:---| | | 각 원소가 values 안에 있는지 (boolean Series) | | | NaN/NaT/None 여부 ( 별칭) | …
[Pandas] query / evalpandas
정의 - : 문자열로 boolean 표현식 을 전달해 행 필터링 - : 문자열로 계산 표현식 을 평가 의 가독성 있는 대안. query 기본 긴 조건일수록 query 가 짧고 읽…

💬 댓글

사이트 검색 / 명령어

검색

스크롤 = 확대/축소 · 드래그 = 이동 · 0 = 원래 크기 · ESC = 닫기