[데이터 전처리] 조건 필터링(filtering)

조건 필터링


데이터 분석에서 원하는 조건에 맞는 행만 추출하는 필터링(filtering) 작업이 자주 발생합니다.

판다스에서는 조건식을 활용한 불리언 인덱싱(Boolean Indexing)으로 이러한 필터링을 간단하게 구현할 수 있습니다. 이는 배열 연산으로 매우 빠르게 동작하기 때문에, 루프를 돌리는 것보다 효율적입니다.

 

 

단일 조건으로 필터링


DataFrame이나 Series에 조건식을 적용하면 True/False 값으로 이루어진 동일한 크기의 불리언 Series가 만들어집니다. 이 값을 인덱싱에 사용하면 True에 해당하는 행만 선택됩니다.

  • 예시 데이터셋:  Seaborn 라이브러리의 팁(tips) 데이터셋을 사용해 보겠습니다.
  • 이 데이터는 레스토랑에서 손님들이 지불한 총 금액(total_bill)과 팁(tip), 방문 요일(day), 식사 시간(time), 흡연 여부(smoker) 등의 정보를 담고 있습니다.
import seaborn as sns

tips = sns.load_dataset('tips')
print(tips.head(5))              : 총 244개의 팁 기록 중 상위 5개만 보여줌
   total_bill   tip     sex smoker  day    time  size
0       16.99  1.01  Female     No  Sun  Dinner     2
1       10.34  1.66    Male     No  Sun  Dinner     3
2       21.01  3.50    Male     No  Sun  Dinner     3
3       23.68  3.31    Male     No  Sun  Dinner     2
4       24.59  3.61    Male     No  Sun  Dinner     4
  • total_bill: 총 청구금액 (달러)
  • tip: 팁으로 낸 금액 (달러)
  • sex: 고객의 성별
  • smoker: 흡연자 여부
  • day: 요일 (Thu, Fri, Sat, Sun 중 하나)
  • time: 식사 시간 (Lunch 또는 Dinner)
  • size: 일행의 규모 (인원 수)

  • 조건식 사용 : 금액이 $5 초과인 경우를 필터링하고 싶다면, 조건식 tips['tip'] > 5를 사용할 수 있습니다.
  • 이는 각 행에 대해 팁이 5보다 큰지 True/False로 평가한 Series를 반환합니다. 이 Series를 다시 원본 데이터프레임에 인덱스로 사용하면 True인 행만 선택됩니다.
high_tips = tips[ tips['tip'] > 5 ]
print(high_tips[['total_bill','tip','day']].head())
    total_bill   tip  day
23       39.42  7.58  Sat
44       30.40  5.60  Sun
47       32.40  6.00  Sun
52       34.81  5.20  Sun
59       48.27  6.73  Sat

위 결과는 팁이 $5 초과인 일부 행을 보여줍니다. (예시로 5개만 출력했습니다.)
실제로는 이런 행이 여러 개 있을 것이고, 모두 팁(tip) 값이 5보다 큰 것을 확인할 수 있습니다. 
조건식을 대괄호 [] 안에 넣어 인덱싱함으로써 매우 간단히 필터링을 수행했습니다.

 

  • 여러 조건 결합: 조건을 여러 개 결합할 때는 논리 연산자 &(AND), |(OR), ~(NOT)을 사용합니다. 이 때 반드시 각 조건을 괄호로 묶고, 파이썬의 and/or 대신 판다스용 &/|를 사용해야 합니다.
  • 예를 들어 요일이 일요일(Sun)이면서 팁이 $5 초과인 경우를 필터링해보겠습니다.
cond = (tips['day'] == 'Sun') & (tips['tip'] > 5)
big_tips_on_sun = tips[cond]
print(big_tips_on_sun[['total_bill','tip','day']].head())
     total_bill   tip  day
44        30.40  5.60  Sun
47        32.40  6.00  Sun
52        34.81  5.20  Sun
116       29.93  5.07  Sun
155       29.85  5.14  Sun

결과를 보면 day 컬럼이 모두 Sun(일요일)이고 tip이 5를 초과한 레코드들만 남았습니다.

 

 

.loc 를 사용한 조건 필터링


앞서 .loc 설명에서 잠깐 언급했듯이, 조건 필터링은 df.loc[ 조건식 ] 형식으로도 쓸 수 있습니다.

예를 들면 tips.loc[tips['time']=='Dinner', :]저녁 식사(Dinner)인 모든 행을 선택합니다. .loc 안에서 콤마 좌측에 조건식을 넣고, 콤마 우측에 :를 넣어 모든 컬럼을 선택했습니다. 이는 tips[tips['time']=='Dinner']와 동일한 결과를 줍니다.

📌   tips.loc[tips['time']=='Dinner', :]       =        tips[tips['time']=='Dinner']

두 문법 모두 널리 쓰이지만, 여러 조건을 연결할 때는 가독성을 위해 위에서처럼 미리 cond 변수에 담아 사용해도 좋습니다.

예제 : 필터링된 데이터 활용

필터링 결과도 데이터프레임이므로, 이어서 다른 연산을 할 수 있습니다.

예를 들어 일요일에 팁을 $5 넘게 준 그룹들의 평균 총 지불 금액은 얼마인지 궁금하다면:

mean_total = big_tips_on_sun['total_bill'].mean()
print(f"일요일에 $5 초과 팁을 준 그룹들의 총 지불액 평균: ${mean_total:.2f}")
                                                      #💡 :.2f 는 소수 둘째까지 보여준다는 뜻
일요일에 $5 초과 팁을 준 그룹들의 총 지불액 평균: $26.39
이처럼 조건 필터링을 한 뒤 통계량을 계산하거나, 새로운 분석을 이어갈 수 있습니다. 조건을 잘 활용하면 필요없는 데이터는 걸러내고 관심있는 부분만 남겨서 분석을 집중할 수 있습니다.