데이터를 다루다 보면 문자열 형태의 날짜 값 중에서 실제로 유효한 형식을 갖춘 날짜만 골라내야 하는 경우가 종종 있습니다. 이 글에서는 파이썬의 pandas와 re(정규표현식) 모듈을 활용해 시리즈(Series)에서 유효한 날짜만 필터링하는 두 가지 방법을 예제와 함께 살펴보겠습니다.
문제 정의
입력 — 다음과 같은 시리즈가 있다고 가정합니다.
0 2010-03-12 1 2011-3-1 2 2020-10-10 3 11-2-2
출력 — 여기서 유효한 날짜만 추출하면 결과는 다음과 같습니다.
0 2010-03-12 2 2020-10-10
'2011-3-1'은 월과 일이 한 자리로 표기되어 있고, '11-2-2'는 연도가 두 자리이기 때문에 'YYYY-MM-DD' 형식 기준으로는 유효하지 않은 날짜입니다.
해결 방법 1 — 반복문과 re.match() 사용
먼저 리스트로부터 시리즈를 정의합니다.
re.match()로 각 요소가 정규표현식 패턴\d{4}\W\d{2}\W\d{2}, 즉 '연도 4자리 + 구분 기호 + 월 2자리 + 구분 기호 + 일 2자리' 형식에 맞는지 검사합니다.패턴과 일치하는 항목만 인덱스와 함께 출력합니다.
예제 코드
import pandas as pd
import re
l = ['2010-03-12', '2011-3-1', '2020-10-10', '11-2-2']
data = pd.Series(l)
for i, j in data.items():
if re.match(r'\d{4}\W\d{2}\W\d{2}', j):
print(i, j)
실행 결과
0 2010-03-12 2 2020-10-10 dtype: object
여기서 \d{4}는 정확히 네 자리 숫자(연도), \W는 하이픈(-)과 같은 비단어(non-word) 문자, \d{2}는 두 자리 숫자(월 또는 일)를 의미합니다.
해결 방법 2 — filter()와 isin() 조합
반복문 대신 내장 함수 filter()에 람다식을 적용해 유효한 날짜를 먼저 골라낸 뒤, isin() 함수로 원본 시리즈에서 해당 값만 선택하는 방법도 있습니다.
예제 코드
import pandas as pd
import re
l = ['2010-03-12', '2011-3-1', '2020-10-10', '11-2-2']
data = pd.Series(l)
result = pd.Series(filter(lambda x: re.match(r'\d{4}\W\d{2}\W\d{2}', x), data))
print(data[data.isin(result)])
실행 결과
0 2010-03-12 2 2020-10-10 dtype: object
참고: 더 유연한 날짜 검증이 필요하다면
위 정규표현식은 월과 일이 반드시 두 자리(예: 03, 12)여야 한다는 제약이 있습니다. '2011-3-1'처럼 한 자리 월·일도 유효한 날짜로 인정하고 싶다면 패턴을 \d{4}\W\d{1,2}\W\d{1,2}로 수정하면 됩니다. 또는 pd.to_datetime(data, errors='coerce')를 사용하면 파싱에 실패한 값이 NaT로 변환되므로, 이를 활용해 유효하지 않은 날짜를 더욱 간편하게 걸러낼 수도 있습니다.