데이터프레임 통한 데이터 가공작업 또는 데이터 클린징이 데이터 분석의 가장~ 시간이 많이 걸리는 부분이고,
심하면 데이터 분석의 80% 가 데이터 클린징 작업이라고 합니다.
오류 데이터에 대한 필터링은 기본이고, 특정 데이터만 추출하거나 변경하는 등 가공작업이 많습니다.
데이터의 상태에 따라 다양한 필터링 조건이 발생되는데 몇가지 예시를 통해 실무에 활용하는데 도움이 되었으면 합니다.
1. 특정 문자열을 포함하는 데이터만 추출 하는 방법
특정 문자열을 포함하는 데이터만 추출 또는 제외하는 것은 빈번한 작업중 하나입니다.
우선 특정 문자열 포함하는 경우
pandas의 str.contains()를 사용할 때 여러 값을 동시에 검색하려면 정규표현식을 사용해 '값1|값2|값3' 형태로 지정하면 됩니다.
✅ 예시: 여러 키워드를 포함하는 행 필터링
import pandas as pd
# 예시 데이터프레임
df = pd.DataFrame({
'내용': ['서울 여행', '부산 출장', '제주 관광', '서울 출근', '대구 회의']
})
# '서울', '제주' 포함된 행 필터링
keywords = ['서울', '제주']
pattern = '|'.join(keywords) # '서울|제주'
filtered_df = df[df['내용'].str.contains(pattern, na=False)]
print(filtered_df)
🔍 설명
- | : 정규표현식에서 "또는(OR)" 의미
- na=False : NaN 값이 있는 경우 False로 간주해 오류 방지
✅ 대소문자 구분 없이 검색하려면
df[df['내용'].str.contains(pattern, case=False, na=False)]
🔍 설명
- case=False : 대소문자 구분을 하지 않겠다는 의미
2. 특정 문자열을 포함하는 경우의 데이터를 제외하는 방법
특정 문자열을 포함하는 데이터만 추출 또는 제외하는 것은 비번한 작업중 하나입니다.
아래 예시 참고
데이터프레임에서 특정 문자열을 포함하는 행을 제외하려면 ~df['컬럼'].str.contains('문자열') 구문을 사용하면 됩니다.
✅ 기본 예제
import pandas as pd
df = pd.DataFrame({
'제품명': ['삼성TV', 'LG냉장고', '삼성에어컨', '위니아에어컨']
})
# '삼성'이 포함된 행 제외
filtered_df = df[~df['제품명'].str.contains('삼성', na=False)]
print(filtered_df)
🔍 설명
- str.contains('삼성') : '삼성'이라는 문자열이 포함된 행은 True
- ~ : True → False, 즉 포함 안 된 것만 남김
- na=False : NaN 값은 False로 처리해서 오류 방지
✅ 여러 문자열 제외하고 싶을 때
# '삼성' 또는 'LG' 포함된 행을 제외
filtered_df = df[~df['제품명'].str.contains('삼성|LG', na=False)]
3. 날짜 타입 데이터 필터 오류 해결방법
날짜 타입 데이터의 경우도 날짜 비교를 통한 추출도 있고, 날짜 데이터가 있는 경우만 추출할 때도 있는 등 다양한 작업이 있습니다.
이중에서 제가 겪었던 오류는 데이터가 있는 경우만 추출할 때 .notnull() 을 사용했는데 오류가 발생되어 수정한 내용입니다.
'통신해지일' 컬럼이 날짜 타입(datetime64[ns])인데도 .notnull()로 필터링이 안 되는 경우는 다음과 같은 숨겨진 결측값 문제가 있을 수 있습니다:
✅ 1. 우선 컬럼에 진짜 NaT (결측치)가 있는지 확인
print(pi_total_contract_comm_end['통신해지일'].isnull().sum())
이 값이 0이라면, NaT처럼 보여도 실제로는 문자열 'NaT', 'None', 또는 공백 문자열일 수 있습니다.
✅ 2. 문자열 기반 결측치 정리 후 datetime으로 변환
# 문자열 'NaT', 'None', '', 등 제거 후 날짜로 변환
pi_total_contract_comm_end['통신해지일'] = pd.to_datetime(
pi_total_contract_comm_end['통신해지일'].replace(['NaT', 'None', ''], pd.NaT)
)
✅ 3. 그런 다음 .notnull() 필터 적용
pi_total_contract_comm_end_filter = pi_total_contract_comm_end[
pi_total_contract_comm_end['통신해지일'].notnull()
]
🔎 확인을 위해 출력
print(pi_total_contract_comm_end_filter[['차량번호', '통신해지일']].head())
👉 그래도 오류가 난 다면 다음과 같은 방법 사용
날짜 컬럼이 datetime 형식인데도 .isnull() 또는 .notnull()이 정상적으로 작동하지 않는 경우는, 컬럼 안에 진짜 NaT가 아니라 다른 타입의 값(예: 문자열 'NaT', 'None', numpy.nan으로 변환 안 된 값 등)이 섞여 있기 때문입니다.
✅ 확실한 해결 방법: 날짜 컬럼을 강제로 정제한 뒤 결측 필터링
다음 단계를 차례로 따라 하세요.
✅ 1. 날짜 컬럼을 문자열로 변환 후 불필요 값 정리
import numpy as np
import pandas as pd
# 문자열로 변환해서 NaT/None/' ' 등 비정상 값들을 NaT 처리
pi_total_contract_comm_end['통신해지일'] = pd.to_datetime(
pi_total_contract_comm_end['통신해지일'].astype(str).replace(['NaT', 'None', '', 'nan'], np.nan),
errors='coerce'
)
- errors='coerce': 날짜 변환 안 되는 값은 NaT로 처리합니다.
✅ 2. 날짜 있는 데이터만 추출 (결측값 제외)
notnull_df = pi_total_contract_comm_end[pi_total_contract_comm_end['통신해지일'].notnull()]
✅ 3. 날짜 없는 데이터만 추출 (결측값만 추출)
null_df = pi_total_contract_comm_end[pi_total_contract_comm_end['통신해지일'].isnull()]
🔍 확인 (테스트용)
print("전체 건수:", len(pi_total_contract_comm_end))
print("날짜 있는 건수:", len(notnull_df))
print("날짜 없는 건수:", len(null_df))
'파이썬(Python)' 카테고리의 다른 글
파이썬-데이터프레임 변환 melt, pivot 함수 사용하기 (2) | 2025.08.17 |
---|---|
파이썬-피봇테이블(pivot table) NaN, 다중컬럼 처리하기 (1) | 2025.08.17 |
파이썬-날짜데이터 포맷 변경하기 (4) | 2025.08.13 |
파이썬-피봇테이블(pivot_table) 컬럼 변경하기 (0) | 2025.08.13 |
파이썬- 숫자로 구성된 데이터의 포맷변환하기 (2) | 2025.08.11 |