Python/Pandas

[Pandas] 파이썬 데이터프레임 문자열 필터링 방법 정리(str.contains)

jimmy_AI 2024. 6. 17. 00:58
반응형

Python의 판다스 모듈에서 str.contains 기능을 통하여

데이터프레임에서 문자열 기준 필터링을 진행하는 방법을

간략하게 정리해보도록 하겠습니다.

 

이해를 돕기 위하여 다음과 같은 간단한 데이터프레임을 하나 가정해보도록 하겠습니다.

import pandas as pd

data = {
    'name': ['AAA', 'BBB', 'CCC', 'DDD', 'EEE'],
    'email': ['aaa@example.com', 'bbb@gmail.com', 'ccc@example.com', 'ddd@example.net', 'eee@gmail.com']
}
df = pd.DataFrame(data)

df

 

 

str.contains 기본 예제

판다스에서 문자열 필터링은 str.contains 메소드를 통하여 진행이 가능합니다.

기본적으로 "해당하는 column의 값에 해당 문자열을 그대로 포함"하는 row들을

최종 결과로 가져오게 됩니다.

 

예시 코드는 다음과 같습니다.

gmail_users = df[df['email'].str.contains('gmail')]
print(gmail_users)

# 결과
  name          email
1  BBB  bbb@gmail.com
4  EEE  eee@gmail.com

email 열에 "gmail"이라는 값이 포함된 1, 4번 인덱스 행들만 필터링된 결과입니다.

 

 

str.contains 대소문자 무시 예제

str.contains를 통한 필터링 과정에서는 기본적으로

대소문자를 완벽히 일치된 결과를 기준으로 합니다.

 

다만, case 인자를 False로 설정하면 대소문자를 무시하고 필터링을

진행한 결과를 받아볼 수 있습니다.

aaa_case_insensitive = df[df['name'].str.contains('aAa', case=False)]
print(aaa_case_insensitive)

# 결과
  name            email
0  AAA  aaa@example.com

name 기준으로 대소문자를 무시하고 a가 3번 연속으로 포함 시 필터링되는 예제입니다.

 

 

str.contains NaN 값 포함 예제

기본적으로 결측치는 필터링 결과에서 모두 제거하지만,

na 인자를 True로 설정하면 NaN 값도 필터링 결과에 포함시킬 수 있습니다.

 

다음과 같이 행 1개의 email 값을 NaN으로 변경해보도록 하겠습니다.

df_with_nan = df.copy()
df_with_nan.loc[1, 'email'] = None

df_with_nan

 

이후, 결측치를 최종 필터링 결과에 포함시킨 결과 예시는 다음과 같습니다.

filtered_with_nan = df_with_nan['email'].str.contains('gmail', na=True)
print(df_with_nan[filtered_with_nan])

# 결과
  name          email
1  BBB           None
4  EEE  eee@gmail.com

 

 

str.contains 정규 표현식 적용

str.contains에는 정규 표현식을 적용한 복합적인 필터링도 가능합니다.

 

다음은 몇 가지 필터링을 시도한 예시 케이스들입니다.

# a로 시작하는 email 기준 필터링 예시
starts_with_a = df[df['email'].str.contains(r'^a')]

# 숫자를 포함하는 name 기준 필터링 예시
names_with_numbers = df[df['name'].str.contains(r'\d')]

# example을 포함하고 .com으로 끝나는 패턴의 email 기준 필터링 예시
example_com_users = df[df['email'].str.contains(r'example.*\.com')]

# gmail.com 또는 example.com을 포함하는 email 기준 필터링 예시
multiple_domains = df[df['email'].str.contains(r'@(gmail|example)\.com')]

# .net으로 끝나는 email 기준 필터링 예시
ends_with_net = df[df['email'].str.contains(r'\.net$')]