[Pandas] str regex (extract / split / replace)
Pandas regex, Pandas str extract, Pandas str split, Pandas str regex, Pandas 정규식
정의
Series.str 의 정규식 기반 메서드. 패턴 추출, 분리, 치환 의 핵심.
str.extract
캡처 그룹으로 부분 문자열을 새 컬럼으로.
python
import pandas as pd
s = pd.Series(['Alice (30)', 'Bob (25)', 'Charlie (40)'])
result = s.str.extract(r'(w+) ((d+))')
result.columns = ['name', 'age']
print(result) 결과
name age
0 Alice 30
1 Bob 25
2 Charlie 40| name | age | |
|---|---|---|
| 0 | Alice | 30 |
| 1 | Bob | 25 |
| 2 | Charlie | 40 |
named group
s.str.extract(r'(?P<name>\w+) \((?P<age>\d+)\)')
# 컬럼이 자동으로 name, age 가 됨
extractall (모든 매치)
s = pd.Series(['Alice and Bob', 'Charlie and Dave'])
s.str.extractall(r'(\w+)')
# 한 행이 여러 매치를 가지면 다중 행으로 expand
str.split
s.str.split(',') # list 반환
s.str.split(',', expand=True) # DataFrame 으로 분리
s.str.split(',', n=1) # 최대 1번 분리
s.str.split(r'\s+', regex=True) # 정규식 분리
df = pd.DataFrame({'full_name': ['Alice Smith', 'Bob Johnson']})
df[['first', 'last']] = df['full_name'].str.split(' ', expand=True)
str.replace
s.str.replace('a', 'A') # 단순 치환 (regex=False, pandas 2.0+ 기본)
s.str.replace(r'\d+', 'X', regex=True) # 정규식
s.str.replace(r'(\w+)@(\w+)', r'\2 / \1', regex=True) # 그룹 참조
IMPORTANT
pandas 2.0 부터 str.replace 의 regex 기본값이 False. 정규식을 쓰려면 명시.
str.findall
s = pd.Series(['call me 010-1234-5678', 'email me at a@b.com'])
s.str.findall(r'\d+')
# 0 [010, 1234, 5678]
# 1 []
str.match vs str.contains vs str.fullmatch
| 메서드 | 매칭 위치 |
|---|---|
contains | 어느 위치든 (re.search) |
match | 시작부터 (re.match) |
fullmatch | 전체 일치 (re.fullmatch) |
s = pd.Series(['abc', 'abcd', 'xabc'])
s.str.contains(r'^abc$') # [True, False, False]
s.str.match(r'abc') # [True, True, False]
s.str.fullmatch(r'abc') # [True, False, False]
실전 예: 이메일 도메인 추출
df['domain'] = df['email'].str.extract(r'@(.+)$')
df['domain'].value_counts()
실전 예: 전화번호 정규화
df['phone'] = (df['phone']
.str.replace(r'\D', '', regex=True) # 숫자만
.str.replace(r'^(\d{3})(\d{4})(\d{4})$', r'\1-\2-\3', regex=True))
함정
1. extract 의 default
extract 는 단일 그룹이면 Series, 여러 그룹이면 DataFrame 반환. expand=False 로 강제 Series.
2. 욕심쟁이 vs 게으른
s.str.extract(r'<(.+)>') # 욕심쟁이, 가능한 한 길게
s.str.extract(r'<(.+?)>') # 게으른, 가능한 한 짧게
3. multiline / dotall
s.str.extract(r'(?ms)^...', flags=re.MULTILINE)
import re
s.str.extract(r'(.+)', flags=re.DOTALL)
💬 댓글