형변환(.astype)
형변환을 하는 이유
데이터가 "무엇인가"에 따라 컴퓨터가 할 수 있는 일이 정해져 있습니다.
- 계산이 필요할 때: 문자열 '100'은 숫자 100과 다릅니다. '100'은 그냥 글자일 뿐이라서 더하기를 하면 오류가 나거나 글자가 이어붙여집니다. 숫자(int/float)로 바꿔야 계산이 가능합니다.
- 분석이 필요할 때: 날짜가 적힌 글자('2026-06-22')는 그냥 글자일 뿐이지만, 날짜 타입(datetime)으로 바꾸면 "오늘이 무슨 요일인지", "지난주와 비교하면 어떤지"를 계산할 수 있습니다.
- 용량 최적화: 메모리를 너무 많이 차지하는 타입을 가벼운 타입으로 바꾸면 대용량 데이터를 다룰 때 훨씬 빠르고 쾌적합니다.
정수형
- .astype(int) 또는 .astype('int64')
- 소수점 아래를 버리고 정수로 변환
# 1. 단일 열 형변환 (문자열 -> 정수)
df['나이'] = df['나이'].astype(int)
df.info(0)
실수형
- .astype(float) 또는 .astype('float64')
- 소수점을 포함하는 실수로 변환
문자열
- .astype(str) 또는 .astype('object')
- 텍스트 데이터로 변환
범주형
- .astype('category')
- 고유값 종류가 적을 때 메모리를 아끼는 타입
숫자 변환 전용(pd.to_numeric())
errors 옵션에 따라 결과가 달라집니다.
- 1. errors='raise'(기본값): 에러를 발생시킵니다
- 2. errors='ignore': 변환하지 않고 원본을 그대로 둠
- 3. errors='coerce': 숫자로 못 바꾸는 것은 결측치(NaN로 처리)(★가장 많이 씀)
s = pd.Series(['10','20','치명적 오류', '40'])
# s.astype(int) -> '치명적 오류' 문자열 때문에 오류
s_converted = pd.to_numeric(s,errors='coerce')
# 'coerce'를 통해 '치명적 오류' -> NaN 으로 변환
s_converted
결측치(NaN)가 있는 열을 int로 바꿀 때, 콤마(,)가 포함된 가격 데이터
# 1) 결측치를 먼저 채우고 변환하기
df['열이름'] = df['열이름'].fillna(0).astype(int)
# 2) 결측치를 사전에 지우거나 다른 값으로 채우고 변환하기
df['열이름'] = df['열이름'].drop(0)
df['열이름'] = df['열이름'].astype(int)
df['열이름'] = df['열이름'].fillna(df['열이름'].mean()).astype(int)
# 콤마(,)가 포함된 가격 데이터 (1, 250)
df['가격'] = df['가격'].str.replace(',').astype(int)
날짜/시간 변환 전용(pd.to_datetime())
문자열로 된 날짜 데이터를 판다스가 인식하는 datetime64 타입으로 바꿔줍니다
자주 쓰는 기본 단위(Unit)
| 약어(추천) | 풀네임 | 의미 |
| 'D' 또는 'd' | 'day' / 'days' | 일 (Days) |
| 'h' | 'hour' / 'hours' | 시간 (Hours) |
| 'm' | 'minute' / 'minutes' | 분 (Minutes) |
| 's' | 'second' / 'seconds' | 초 (Seconds) |
format='mixed'
df = pd.DataFrame({'날짜': ['2026-01-01','2026/05/15','2026.12.25']})
print(df.info())
df['날짜'] = pd.to_datetime(df['날짜'], format='mixed')
# format='mixed': 형태가 다 다를 때 문자열에서 바로 변환할 때 사용
# errors='coerce': 유효하지 않은 문자열은 NaN으로 변환
print(df.info())
df= pd.DataFrame({'날짜': ['20260617','20260618']})
df['날짜'] = pd.to_datetime(df['날짜'], format='%Y%m%d')
df
연, 월, 일 추출 (수치형 데이터로 변환됨)
df['연도'] = df['날짜'].dt.year
df['월'] = df['날짜'].dt.month
df['일'] = df['날짜'].dt.day
df.info()
요일 추출 (0: 월요일, 1: 화요일, ..., 6: 일요일 | Monday, Tuesday, ... )
# 요일 추출 (0: 월요일, 1: 화요일, ..., 6: 일요일)
df['요일_숫자'] = df['날짜'].dt.weekday
df
# 요일 이름 추출 (Mnonday, Tuesday 등)
df['요일_이름'] = df['날짜'].dt.day_name()
df
날짜 연산 (timedelta)
# 두 날짜의 차이 구하기 (날짜 연산 사용시 타입: timedelta)
df_user['유지기간'] = df_user['탈퇴일'] - df_user['가입일']
# timedelta 형태로 바꾸기
pd.to_timedelta(df_user['유지일수'], unit='D')
import pandas as pd
df_user = pd.DataFrame({
'가입일': pd.to_datetime(['2025-01-01','2025-03-15']),
'유지일수': [537, 285] # 정수형 일수 데이터
})
# 정수형 숫자를 날짜 간격(Days) 데이터로 변환하여 더하기
df_user['복구일'] = df_user['가입일'] + pd.to_timedelta(df_user['유지일수'], unit = 'D')
df_user
' 정수형 숫자(일수)'만 추출하기 (.dt.days)
# '정수형 숫자(일수)'만 추출하기 (.dt.days)
df_user['유지일수'] = df_user['유지기간'].dt.days
중복 데이터 처리(.duplicated)
import pandas as pd
data = {
'이름': ['김철수', '이영희', '박민수', '정미영', '강지아', '최현우', '송은지', '송은지'],
'나이': [25, 30, 50, 28, 32, 35, 29, 29],
'몸무게': [75.0, 55.0, 68.0, 63.7, 52.0, 80.0, 58.0, 58.0],
'생년월일': ['20000101', '1994-05-15', '1993-08-22', '1996-02-28', '1998-11-30', '1989-07-12', '1995-03-18', '1995-03-18'],
'급여': [3500000, 3985714, 4200000, 3800000, 3600000, 5000000, 3900000, 3900000]
}
df = pd.DataFrame(data)
df
df.duplicated().sum()
df.duplicated()
df[df.duplicated()]
df.drop_duplicates() # 원본은 삭제 안됨
df.duplicated() (반환 타입: Series(true/false))
- 결과: 각 행이 중복인지 여부를 알려주는 True와 False로 이루어진 리스트(Series)를 반환합니다.
- 의미:
- False: 이 행은 처음 등장함 (중복 아님)
- True: 이 행은 이전에 이미 등장했음 (중복됨)
df.duplicated().sum() (반환 타입: 숫자(int))
- 결과: 전체 데이터에서 중복된 행이 총 몇 개인지 나타내는 '숫자'를 반환합니다.
- 의미: True인 행의 개수를 모두 더한 값이므로, 데이터에 전체적으로 중복이 몇 건 있는지 빠르게 파악할 때 사용합니다.
df[df.duplicated()] (반환 타입: DataFrame)
- 결과: 중복된 행들만 실제로 추출해서 보여주는 '데이터프레임'을 반환합니다.
- 의미: "도대체 어떤 데이터들이 중복되어 있는 거지?" 하고 직접 눈으로 확인하고 싶을 때 사용합니다. (df 전체에서 중복인 행만 필터링한 결과입니다.)
df.drop_duplicates() (반환 타입: DataFrame)
- 결과: 중복된 행을 제거한 '새로운 데이터프레임'을 반환합니다.
- 의미: 말 그대로 중복을 정리하는 명령어입니다. (기본적으로 첫 번째 등장한 행은 살려두고, 뒤에 나타나는 중복값들을 삭제합니다.)
그룹화(Group By)
방대한 데이터를 특정 기준에 따라 분류하고, 그룹별로 통계 정보를 요약하기 위해 사용하는 핵심 기능
import pandas as pd
data = [['김민재', 31, 75, 5428000],
['이강인', 22, 57, None],
['박찬호', 50, None, 8428000],
['차범근', 70, 80, 4428000],
['추신수', 43, 100, 4528000],
['손흥민', 31, 72, 7028000],
['황희찬', 28, 69, 2528000]]
df = pd.DataFrame(data, columns=['성명', '나이', '몸무게', '급여'])
df
df['나이'].unique()
df['종목'] = ['축구','축구','야구','축구','야구','축구','축구']
df
인덱스(Index) 변경
df7 = df.copy()
df7.index = ['A','B','C','D','E','F','G']
df8 = df7.set_index('성명') # 기존 컬럼(열)을 index로
df8
df9 = df8.reset_index() # index를 컬럼(열)으로
df9
df9 = df8.reset_index(drop=True) # index를 버림
df9
set_index()
특정 컬럼을 인덱스로 변경
reset_index()
인덱스를 다시 일반 컬럼으로 변경
drop=True : 기존 인덱스를 삭제하고 새 인덱스를 생성한다
그룹화(GroupBy)
groupby()
특정 컬럼을 기준으로 데이터를 그룹으로 묶는다.
그룹별 합계 구하기(sum())
df_grp = df.groupby('나이').sum()
df_grp
결과
몸무게 급여
나이
22 57.0 0
31 147.0 12456000
43 100.0 4528000
...
특정 그룹 조회, 평균 구하기
# 특정 그룹 조회
df_grp.loc[31]
'''
몸무게 147.0
급여 12456000
'''
# 특정 컬럼 평균
df_hap = df.groupby('종목')[['나이','몸무게','급여']].mean()
df_hap
'''
나이 몸무게 급여
종목
야구 46.5 100.0 6478000
축구 36.4 70.6 4853000
'''
# 숫자형 컬럼 전체 평균(숫자형 컬럼만 자동 선택하여 평균 계산)
df.groupby('종목').mean(numeric_only=True)
다중 그룹화(Multi GroupBy)
df = pd.DataFrame({
'제품':['노트북','태블릿','스마트폰','노트북','스마트폰','태블릿'],
'지역':['서울','부산','서울','대구','부산','서울'],
'판매량':[10,5,8,12,6,4],
'가격':[1200000,500000,800000,1300000,750000,550000],
'판매자번호':['A01','A02','A01','A03','A02','A03']
})
제품별 평균 판매량/지역+제품별 판매량
# 제품별 판매량
df.groupby('제품')[['판매량']].mean()
'''
판매량
제품
노트북 11.0
스마트폰 7.0
태블릿 4.5
'''
# 지역, 제품별 판매량
df_prd = df.groupby(['지역','제품'])[['판매량']].sum()
df_prd
'''
판매량
지역 제품
부산 스마트폰 6
부산 태블릿 5
대구 노트북 12
서울 노트북 10
서울 스마트폰 8
서울 태블릿 4
'''
특정 그룹 조회
# 서울 전체 조회
df_prd.loc[['서울']]
'''
판매량
제품
노트북 10
스마트폰 8
태블릿 4
'''
# 서울 스마트폰 판매량
df_prd.loc[[('서울','스마트폰')]]
'''
판매량
지역 제품
서울 스마트폰 8
'''
다중 인덱스(Multi Index)는 튜플 (지역, 제품) 형태로 조회한다.
agg() 집계 함수
여러 집계 함수를 한 번에 적용할 수 있다.
문법
df.groupby('컬럼').agg({
'컬럼명':['함수1','함수2']
})
예제
result = df.groupby('제품').agg({
'판매량':['sum','mean','count'],
'가격':['min','max']
})
결과
판매량 가격
sum mean count min max
제품
노트북 22 11.0 2 1200000 1300000
스마트폰 14 7.0 2 750000 800000
태블릿 9 4.5 2 500000 550000
——————————————————————————
본 후기는 [한글과컴퓨터x한국생산성본부x스나이퍼팩토리] 한컴 AI 아카데미 (B-log) 리뷰로 작성 되었습니다.
'학습일지' 카테고리의 다른 글
| [스나이퍼팩토리] 한컴AI아카데미(26.06.24) KNN 알고리즘, GridSearchCV (0) | 2026.06.24 |
|---|---|
| [스나이퍼팩토리] 한컴AI아카데미(26.06.23) 머신러닝, (의사결정나무알고리즘) (0) | 2026.06.23 |
| [스나이퍼팩토리] 한컴AI아카데미(26.06.19) Pandas 데이터 전처리 정리 (0) | 2026.06.19 |
| [스나이퍼팩토리] 한컴AI아카데미(26.06.17) Pandas (0) | 2026.06.17 |
| [스나이퍼팩토리] 한컴AI아카데미(26.06.11) JWT 기반 인증 (0) | 2026.06.11 |