학습일지

[스나이퍼팩토리] 한컴AI아카데미(26.06.22) Pandas 그룹화/형변환

cd-record 2026. 6. 22. 18:00

 

형변환(.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) 리뷰로 작성 되었습니다.