types_dup
데이터 정제 과정에서 숫자 컬럼의 콤마 제거, 날짜 형식 통일, 그리고 중복 데이터를 제거하고 저장하는 핵심 절차다.
📌 타입 정제 및 중복 제거 3단계 프로세스
| 단계 | 작업 항목 | 핵심 목적 | 주요 메서드 및 키워드 |
| 1단계 | 숫자 변환 | 콤마(,) 제거 후 숫자 타입으로 안전하게 변환 | str.replace(',', ''), pd.to_numeric(errors='coerce') |
| 2단계 | 날짜 변환 | 섞여 있는 날짜 형식을 datetime 타입으로 통일 | pd.to_datetime(format='mixed'), dt.dayofweek |
| 3단계 | 중복 제거 및 저장 | 기준열 기준 중복 행 제거 후 데이터 프레임 저장 | drop_duplicates(keep='first'), to_pickle() |
1. 숫자 변환 (순서가 중요)
숫자 데이터에 콤마(,)가 포함되어 있으면 to_numeric 변환 시 결측 처리된다. 따라서 콤마를 먼저 제거한 뒤 숫자로 변환해야 한다.
- errors="coerce": 숫자로 못 변경하는 값을 에러 대신 NaN으로 만든다. (기본값인 errors="raise"는 하나라도 변환이 안 되면 실행이 멈춤)
# 1. 콤마를 지우지 않고 변환
naive = pd.to_numeric(df["close"], errors="coerce")
print(f" close 결측 : {naive.isna().sum()}건")
# 2. 콤마를 먼저 지우고 변환
proper = pd.to_numeric(
df["close"].astype(str).str.replace(",", "", regex=False), errors="coerce"
)
print(f" close 결측 : {proper.isna().sum()}건")
print(f" 차이 : {naive.isna().sum() - proper.isna().sum()}건")
# 전체 숫자 열 변환
for col in NUM_COLS:
df[col] = pd.to_numeric(
df[col].astype(str).str.replace(",", "", regex=False), errors="coerce"
)
print(f"전체 숫자 열 변환 후 dtypes :")
print(df[NUM_COLS].dtypes.to_string())
print(f"\n변환 후 결측 : ")
for col in NUM_COLS:
n = df[col].isna().sum()
if n:
print(f"{col} : {n}건")
2. 날짜 형식 변환
데이터 내 날짜 형식이 yyyy-mm-dd, yyyy.mm.dd, yyyymmdd 형태로 섞여 있을 수 있다.
- parse_dates로 변경 시 형식이 섞여 있다면 str로 먼저 변경 후 변환한다.
- pd.to_datetime(s, format="mixed"): 형식이 섞여 있는 날짜 데이터를 datetime 타입으로 자동 변환한다.
- .dt.dayofweek: 요일을 숫자로 반환하며, 5 이상(>= 5)인 경우 주말(토, 일)을 의미한다.
raw_dates = df["date"].astype(str)
dot = raw_dates.str.contains(r"\.", regex=True)
eight = raw_dates.str.len() == 8
print(f" yyyy-mm-dd 형식 : {(~dot & ~eight).sum()}건 예 : {raw_dates[~dot & ~eight].iloc[0]}")
print(f" yyyy.mm.dd 형식 : {dot.sum()}건 예 : {raw_dates[dot].iloc[0]}")
print(f" yyyymmdd 형식 : {eight.sum()}건 예 : {raw_dates[eight].iloc[0]}")
# 날짜 타입 변환
df["date"] = pd.to_datetime(df["date"], format="mixed")
print(f" dtype : {df['date'].dtype}")
print(f" 변환 실패 : {df['date'].isna().sum()}건")
# 주말 건수 확인
print(f" 주말 : {(df['date'].dt.dayofweek >= 5).sum()}건")
3. 중복 제거 및 데이터 저장
- df.duplicated(subset=["code", "date"]): 기준 열 조합의 중복 여부를 확인한다.
- df.drop_duplicates() 옵션:
- keep="first" -> 첫 행만 남김
- keep="last" -> 마지막 행만 남김
- keep=False -> 중복된 데이터 둘 다 제거
- to_pickle / read_pickle:
- df.to_pickle(경로) -> DataFrame을 pickle 파일로 저장한다. (리턴값 없음)
- pd.read_pickle(경로) -> 저장한 DataFrame을 그대로 읽어온다.
# 중복 확인
dup = df.duplicated(subset=["code", "date"]).sum()
print(f" (code, date) 중복 : {dup}건")
# 중복 제거 (첫 행만 남기고 인덱스 재설정)
df = df.drop_duplicates(subset=["code", "date"], keep="first").reset_index(drop=True)
print(f" 중복 제거 후 : {len(df)}행")
# 중간 정제 데이터 저장
print("====df 저장=====")
df.to_pickle(step_path('_step1.pkl'))
4. 핵심 메서드 및 옵션 요약
| 구분 | 메서드 / 옵션 | 기능 및 역할 |
| 숫자 변환 | str.replace(',', '', regex=False) | 문자열 내 콤마(,)를 빈 값으로 변경 |
| to_numeric(errors='coerce') | 변환 불가능한 값은 에러 대신 NaN으로 변환 | |
| 날짜 변환 | to_datetime(format='mixed') | 여러 서식이 섞인 날짜 문자를 datetime64로 통일 |
| dt.dayofweek | 날짜에서 요일 추출 (0:월 ~ 6:일, 5 이상은 주말) | |
| 중복 처리 | drop_duplicates(keep='first') | 중복 데이터 중 첫 번째 행만 남기고 제거 |
| 파일 저장 | to_pickle() / read_pickle() | DataFrame 타입 및 구조를 유지한 채 파일 저장/로드 |
'- > Pandas' 카테고리의 다른 글
| Pandas: 데이터 결측 처리 전략 및 시계열 보간 (0) | 2026.08.30 |
|---|---|
| Pandas: 이상치 탐색 (0) | 2026.08.30 |
| Pandas: diagnose (0) | 2026.08.30 |
| Pandas: groupby() (0) | 2026.08.28 |
| Pandas: 열 다루기와 타입 변환 (0) | 2026.08.28 |