수달이네 기술 블로그

2. Pandas 본문

AI공부/머신러닝

2. Pandas

슬픈 수달이 2025. 11. 17. 23:08

판다스(Pandas)

데이터 분석을 위한 파이썬 라이브러리, 표, 데이터등 다양한 형태의 데이터를 처리하고 분석하는 도구

pip install pandas

위 코드를 이용하여 설치 가능하다.

import pandas as pd

판다스를 import후 pd라는 별명으로 사용할 것이다.

Series 와 DataFrame

1. Series

1차원 배열과 같은 자료구조로 하나의 열을 나타냄.

  • 인덱스, 값으로 구성되어있음.
import pandas as pd

idx = ['김사과', '반하나', '오렌지', '이메론', '배애리']
data = [67, 75, 90, 62, 98]

# pd.Series(데이터, 인덱스, ...)
pd.Series(data)

# 0    67
# 1    75
# 2    90
# 3    62
# 4    98
# dtype: int64
  • 값은 ndarray기반으로 저장된다.
se1 = pd.Series(data, idx)
se1

# 김사과    67
# 반하나    75
# 오렌지    90
# 이메론    62
# 배애리    98
# dtype: int64
  • pd.Series(인덱스, 데이터)로 저장된다.
  • 정수, 실수, 문자열등 다양한 형태의 데이터를 담을 수 있다.

2. DataFrame

2차원 테이블 형태의 데이터를 다루는데 사용되는 자료구조

data = [[67, 93, 91],
        [75, 68, 96],
        [87, 81, 82],
        [62, 70, 75],
        [98, 56, 87]]

idx = ['김사과', '반하나', '오렌지', '이메론', '배애리']
col = ['국어', '영어', '수학']
# pd.DataFrame(데이터, 인덱스, 컬럼, ...)
pd.DataFrame(data)

 

  0 1 2
0 67 93 91
1 75 68 96
2 87 81 82
3 62 70 75
4 98 56 87
  • 위와 같은 결과로 출력된다.
  • 인덱스가 지정되지 않았을 경우 0~n까지 자동으로 입력된다.
pd.DataFrame(data, idx)

 

  0 1 2
김사과 67 93 91
반하나 75 68 96
오렌지 87 81 82
이메론 62 70 75
배애리 98 56 87
  • 인덱스를 지정해주면 정해진 인덱스로 인덱스가 출력된다.
pd.DataFrame(data, idx, col)

 

  국어 영어 수학
김사과 67 93 91
반하나 75 68 96
오렌지 87 81 82
이메론 62 70 75
배애리 98 56 87
  • 컬럼을 지정해주면 컬럼도 지정 가능하다.
df = pd.DataFrame(index=idx, columns=col, data=data)
df
  • 명확하게 해줄 수도 있다.
print(df.index)
print(df.columns)
print(df.values)

# Index(['김사과', '반하나', '오렌지', '이메론', '배애리'], dtype='object')
# Index(['국어', '영어', '수학'], dtype='object')
# [[67 93 91]
#  [75 68 96]
#  [87 81 82]
#  [62 70 75]
#  [98 56 87]]
  • 위처럼 인덱스 컬럼, 값을 따로 출력 가능하다.

CSV파일 읽기

df = pd.read_csv("파일위치")
df

위와 같이 읽어줄 수 있다.

  이름 그룹 소속사 성별 생년월일 혈액형
0 지민 방탄소년단 빅히트 남자 1995-10-13 174.0 A
1 정국 방탄소년단 빅히트 남자 1997-09-01 179.0 A
2 민지 뉴진스 어도어 여자 2004-05-07 169.0 A
  • csv파일은 dataframe타입이다.

1. 데이터 프레임 기본 정보 알아보기

df.info()

# <class 'pandas.core.frame.DataFrame'>
# RangeIndex: 20 entries, 0 to 19
# Data columns (total 8 columns):
#  #   Column   Non-Null Count  Dtype  
# ---  ------   --------------  -----  
#  0   이름       20 non-null     object 
#  1   그룹       20 non-null     object 
#  2   소속사      19 non-null     object 
#  3   성별       20 non-null     object 
#  4   생년월일     20 non-null     object 
#  5   키        19 non-null     float64
#  6   혈액형      19 non-null     object 
#  7   브랜드평판지수  20 non-null     int64  
# dtypes: float64(1), int64(1), object(6)
# memory usage: 1.4+ KB

위와 같이 info함수를 사용하면 컬럼, 데이터 형태, 결측값 등을 확인할 수 있다.

df.columns

# Index(['이름', '그룹', '소속사', '성별', '생년월일', '키', '혈액형'], dtype='object')
  • 데이터 프레임이므로 컬럼을 확인할 수도 있다.
new_columns = ['name', 'group', 'company', 'gender', 'birthday', 'height', 'blood', 'brand']
df.columns = new_columns
df
  name group company gender birthday height blood
0 지민 방탄소년단 빅히트 남자 1995-10-13 174.0 A
1 정국 방탄소년단 빅히트 남자 1997-09-01 179.0 A
2 민지 뉴진스 어도어 여자 2004-05-07 169.0 A
  • 위처럼 컬럼명을 수정해줄 수 있다.
# describe(): 통계 정보를 반환
df.describe()

 

  height brand
count 19.000000 2.000000e+01
mean 170.536842 2.700190e+06
std 7.225204 1.381919e+06
min 161.000000 1.680587e+06
25% 164.750000 1.887423e+06
50% 168.000000 2.074682e+06
75% 179.000000 2.623465e+06
max 182.000000 6.267302e+06

위와 같이 통계값(개수, 평균, 정규값, 최소값 등등)을 확인할 수도 있다.

  • 위의 값을 보면 계산 가능한 int값만 적용되었는데,
df.describe(include=object) # Top: 최빈값, freq: 최빈값의 빈도

위처럼 object를 포함하는 것으로 해주면

  name group company gender birthday blood
count 20 20 19 20 20 19
unique 20 6 5 2 20 4
top 지민 방탄소년단 빅히트 여자 1995-10-13 A
freq 1 5 7 13 1 11
  • object값만 포함하여 object로 계산가능한 통계값을 출력해준다
  • 개수, 종류, 최빈값, 최빈값의 빈도 순이다.
# 원하는 개수의 데이터 보기
df.head(원하는 개수) # 상위 5개의 row를 출력
  name group company gender birthday height blood
0 지민 방탄소년단 빅히트 남자 1995-10-13 174.0 A
1 정국 방탄소년단 빅히트 남자 1997-09-01 179.0 A
2 민지 뉴진스 어도어 여자 2004-05-07 169.0 A
3 하니 뉴진스 어도어 여자 2004-10-06 161.7 O
4 방탄소년단 빅히트 남자 1995-12-30 179.0 AB
  • 기본 상위 5개의 데이터를 보여주며, 원하는 개수에 정수값을 입력하면 그개수만큼의 값을 보여준다.
df.tail(원하는 개수) # 하위 5개의 row를 출력
  name group company gender birthday height blood
15 윤아 소녀시대 에스엠 여자 1990-05-30 168.0 B
16 조이 레드벨벳 빅히트 여자 1996-09-03 168.0 A
17 슬기 레드벨벳 빅히트 여자 1994-02-10 161.0 A
18 강다니엘 워너원 NaN 남자 1996-12-10 182.0 A
19 방탄소년단 빅히트 남자 1992-12-04 179.0 O
  • 기본 하위 5개의 데이터를 보여주며 원하는 개수에 정수값을 입력하면 그 개수만큼의 값을 렬

2. 정렬

# 정렬하기
df.sort_index([ascending=False]) # index로 오름차순 정렬: 기본값
  name group company gender birthday height blood
0 지민 방탄소년단 빅히트 남자 1995-10-13 174.0 A
1 정국 방탄소년단 빅히트 남자 1997-09-01 179.0 A
2 민지 뉴진스 어도어 여자 2004-05-07 169.0 A
3 하니 뉴진스 어도어 여자 2004-10-06 161.7 O
4 방탄소년단 빅히트 남자 1995-12-30 179.0 AB
5 다니엘 뉴진스 어도어 여자 2005-04-11 165.0 NaN
  • 위 함수로 인덱스 값으로 정렬해준다.
  • 기본 오름차순이며, ascending = False를 할 경우 내림차순으로 정렬해준다.
df.sort_values(by='컬럼', [ascending=False], [na_position='first'])# 키로 오름차순 정렬
  • 위 함수로 원하는 컬럼을 기준으로 정렬해준다. 마찬가지로 ascending을 통해 내림차순으로 변경할 수 있다.
  • na_position을 통해 nan값을 맨 앞으로 끌어올려줄 수도 있다.
# 1차 정렬: 키(내림차순), 2차 정렬: 브랜드(내림차순)
df.sort_values(by=['height', 'birthday'], ascending=[False, False], na_position='first')
  • 만약 위처럼 배열 값을 컬럼으로 넣어부면 1차 정렬 후 같은 값을 2차 정렬 시켜준다.

데이터 다루기

df['blood']

# 0       A
# 1       A
# 2       A
# 3       O
# 4      AB
# 5     NaN
# 6       O
# 7       A
# 8       B
# 9       A
# 10      A
# 11      B
# 12      A
# 13      A
# 14      B
# 15      B
# 16      A
# 17      A
# 18      A
# 19      O
# Name: blood, dtype: object
  • 위처럼 컬럼 값을 지정해주면, 인덱스와 해당하는 컬럼값만 추출 가능하다.
df[:3]

 

  name group company gender birthday height blood
0 지민 방탄소년단 빅히트 남자 1995-10-13 174.0 A
1 정국 방탄소년단 빅히트 남자 1997-09-01 179.0 A
2 민지 뉴진스 어도어 여자 2004-05-07 169.0 A

위처럼 인덱스 값을 이용하여 간단하게 원하는 값만 출력해줄 수도 있다.

loc인덱싱

# loc 인덱싱: 컬럼 인덱싱
df.loc[3:5, 'name'] # df['name']

# 3     하니
# 4      뷔
# 5    다니엘
# Name: name, dtype: object
  • 인덱싱도 쉽게 가능하다.
  • 컬럼값에 여러개를 넣으면 dataframe(표)의 형태로 보여준다.
df.loc[2:5, 'name':'gender']
  name group company gender
2 민지 뉴진스 어도어 여자
3 하니 뉴진스 어도어 여자
4 방탄소년단 빅히트 남자
5 다니엘 뉴진스 어도어 여자

iloc인덱싱

df.iloc[:, 0:3] # 3을 포함하지 않음

 

  name group company
0 지민 방탄소년단 빅히트
1 정국 방탄소년단 빅히트
2 민지 뉴진스 어도어
3 하니 뉴진스 어도어
4 방탄소년단 빅히트
  • 위처럼 iloc를 사용하면 데이터 이름이 아닌 숫자를 통해 컬럼 인덱싱 가능하다.

데이터 값으로 인덱싱

df['height'] >= 180
# 0     False
# 1     False
# 2     False
# 3     False
# 4     False
# 5     False
# 6     False
# 7     False
# 8     False
# 9     False
# 10     True
# 11    False
# 12    False
# 13    False
# 14    False
# 15    False
# 16    False
# 17    False
# 18     True
# 19    False
# Name: height, dtype: bool

위처럼 데이터 값을 통해서 결과값을 출력하면 결과에 해당하는 값만 True로 반환된다.

df[df['height'] >= 180]

해당 값을 df내에 넣을 경우’

  name group company gender birthday height blood
10 RM 방탄소년단 빅히트 남자 1994-09-12 181.0 A
18 강다니엘 워너원 NaN 남자 1996-12-10 182.0 A

위처럼 해당하는 값만 인덱싱 되어 출력된다.

company = [ '어도어']
df['company'].isin(company)

# 0     False
# 1     False
# 2      True
# 3      True
# 4     False
# 5      True
# 6      True
# 7     False
# 8      True
# 9     False
# 10    False
# 11    False
# 12    False
# 13    False
# 14    False
# 15    False
# 16    False
# 17    False
# 18    False
# 19    False
# Name: company, dtype: bool

원하는 값을 포함하는 값을 출력시키려면 위처럼 배열로 object를 만들어주고

마찬가지로 값을 넣어주면 된다.

df[df['company'].isin(company)]
  name group company gender birthday height blood
2 민지 뉴진스 어도어 여자 2004-05-07 169.0 A
3 하니 뉴진스 어도어 여자 2004-10-06 161.7 O
5 다니엘 뉴진스 어도어 여자 2005-04-11 165.0 NaN
6 혜인 뉴진스 어도어 여자 2008-04-21 170.0 O
8 해린 뉴진스 어도어 여자 2006-05-15 164.5 B
  • 위처럼 ‘어도어’인 컴퍼니만 만들어진다.

결측값

df.info()

# <class 'pandas.core.frame.DataFrame'>
# RangeIndex: 20 entries, 0 to 19
# Data columns (total 8 columns):
#  #   Column    Non-Null Count  Dtype  
# ---  ------    --------------  -----  
#  0   name      20 non-null     object 
#  1   group     20 non-null     object 
#  2   company   19 non-null     object 
#  3   gender    20 non-null     object 
#  4   birthday  20 non-null     object 
#  5   height    19 non-null     float64
#  6   blood     19 non-null     object 
#  7   brand     20 non-null     int64  
# dtypes: float64(1), int64(1), object(6)
# memory usage: 1.4+ KB

위에서 Non-Null Count에서 나오는 20 non-null은 null값이 아닌 데이터의 수이다. 즉, 20개의 데이터가 있는 현제 데이터에서 19 non-null이라고 나오는 값은 1개의 결측값이 존재한다는 의미이다.

혹은, 위에서 NaN이라고 출력되던 값이 결측값들이다.

df.isna()
df.isnull()

해당 함수를 통해서 결측값인 경우 True로 출력된다.

  name group company gender birthday height blood
0 False False False False False False False
1 False False False False False False False
2 False False False False False False False
3 False False False False False False False
4 False False False False False False False
5 False False False False False False True
6 False False False False False False False
7 False False False False False False False
8 False False False False False False False
9 False False False False False True False
10 False False False False False False False
11 False False False False False False False
12 False False False False False False False
13 False False False False False False False
14 False False False False False False False
15 False False False False False False False
16 False False False False False False False
17 False False False False False False False
18 False False True False False False False
19 False False False False False False False

반대로는

df.notnull()

이 존재한다.

df['height'].isna()

# 0     False
# 1     False
# 2     False
# 3     False
# 4     False
# 5     False
# 6     False
# 7     False
# 8     False
# 9      True
# 10    False
# 11    False
# 12    False
# 13    False
# 14    False
# 15    False
# 16    False
# 17    False
# 18    False
# 19    False
# Name: height, dtype: bool

위처럼 컬럼에서 결측값을 확인할 수 있으며 마찬가지로 df[]에 넣어주면 해당하는 데이터프레임만 확인 가능하다.

# fillna(): 결측값을 채워주는 함수
df['height'].fillna(0) # df['height].fillna(0, inplace=True) 적용

# 0     174.0
# 1     179.0
# 2     169.0
# 3     161.7
# 4     179.0
# 5     165.0
# 6     170.0
# 7     162.0
# 8     164.5
# 9       0.0
# 10    181.0
# 11    163.0
# 12    179.0
# 13    167.0
# 14    168.0
# 15    168.0
# 16    168.0
# 17    161.0
# 18    182.0
# 19    179.0
# Name: height, dtype: float64

fillna()함수로 결측값을 채워줄 수 있으며, 위에선 0으로 채워넣었다.

이때 df.copy()함수를 통해 데이터프레임을 복사해줄 수 있는데, 이걸 이용하면

  • 위에서 copy를 사용하는 이유는 현재 실행중인 프로그램의 원본 데이터 값을 건드리지 않기 위해
height = df_copy['height'].mean()
df_copy['height'] = df_copy['height'].fillna(height)
df_copy['height']

# 0     174.000000
# 1     179.000000
# 2     169.000000
# 3     161.700000
# 4     179.000000
# 5     165.000000
# 6     170.000000
# 7     162.000000
# 8     164.500000
# 9     170.536842
# 10    181.000000
# 11    163.000000
# 12    179.000000
# 13    167.000000
# 14    168.000000
# 15    168.000000
# 16    168.000000
# 17    161.000000
# 18    182.000000
# 19    179.000000
# Name: height, dtype: float64

  • copy로 height의 평균을 계산하고, 해당 값을 fillna로 넣어주는 방식을 사용할 수 있따.
height = df_copy['height'].median() # 50%값, 중위
height
  • 중앙값을 넣어줄 수도 있다.
# dropna(): 결측값이 있는 행 또는 열을 제거. 결측값이 한개라도 있는 경우 삭제
# axis=0 (행 삭제)
# axis=1 (열 삭제)
df_copy.dropna([axis=0])
  • 혹은 위와 같이 행 자체를 삭제해 줄 수도 있다.
  • 기본 axis = 0이며 1로 설정해주면 결측값 열을 삭제해 줄수도 있다.

데이터 추가(행, 열)

dic = {
    'name': '김사과',
    'group': '과수원',
    'company': '애플',
    'gender': '여자',
    'birthday': '2000-01-01',
    'height': 160.0,
    'blood': 'A',
    'brand': 1234567
}

# concat(): 데이터를 합침. axis=0 (기본값)
df_copy = pd.concat([df_copy, pd.DataFrame(dic, index=[0])], ignore_index=True)
df_copy.iloc[-1]

# name               김사과
# group              과수원
# company             애플
# gender              여자
# birthday    2000-01-01
# height           160.0
# blood                A
# brand          1234567
# Name: 25, dtype: object

위와 같이 데이터 행을 추가 가능하다.

df_copy['nation'] = '대한민국'
df_copy.head()
# name	group	company	gender	birthday	height	blood	brand	nation
# 0	지민	방탄소년단	빅히트	남자	1995-10-13	174.0	A	6267302	대한민국
# 1	정국	방탄소년단	빅히트	남자	1997-09-01	179.0	A	5805844	대한민국

새로운 행을 추가해주려면 위와 같이 사용해 줄 수 있따.

df_copy.loc[df_copy['name'] == '김사과', 'nation'] = '미국'
df_copy.tail()

위와 같은 식으로 원하는 행의 내용을 수정해줄 수 있다.

# 행 제거하기
df_copy.drop(20, axis=0) # 0: 행, 1: 열
df_copy.drop([1, 3, 5, 7, 20], axis=0) 

행은 drop으로 제거 가능하고

(위처럼 여러 행을 한번에 제거도 가능하다)

# 열 제거하기
df_copy.drop('nation', axis=1)

열또한 drop으로 제거 가능한데 axis = 1로 하면 제거 가능하다.

df_copy.drop(['nation', 'group'], axis=1)

위처럼 여러행 제거도 가능

통계함수

아까 사용했던 describe함수를 이용할 때 사용했던 여러 통계값을 직접 찾아볼 수도 있다.

df_copy['height'].sum() # 합계
df_copy['height'].count() # 개수, NaN은 포함하지 않음
df_copy['height'].mean() # 평균
df_copy['height'].median() # 중앙값
df_copy['height'].max() # 최대값
df_copy['height'].min() # 최소값
df_copy['height'].var() # 분산
df_copy['height'].std() # 표준편차
  • 평균: 모든 데이터의 합 / 데이터 개수
  • 중앙값: 데이터를 크기순으로 정렬했을때 가운데값
  • 분산: 얼마나 데이터가 평균에서 퍼쳐있는지
  • 표준편차: 분산의 제곱근(이것또한 분포정도를 측정)

그룹

그룹을 통해 데이터를 그룹으로 묶어서 분석하는데에 사용한다.

# 그룹을 맺으면 통계함수를 사용할 수 있음
df_copy.groupby('group').count()
group name company gender birthday height blood brand
뉴진스 5 5 5 5 5 4 5
레드벨벳 2 2 2 2 2 2 2
방탄소년단 5 5 5 5 5 5 5
블랙핑크 4 4 4 4 4 4 4
소녀시대 2 2 2 2 1 2 2
워너원 2 1 2 2 2 2 2
  • 위 코드는 그룹으로 데이터를 묶어준 이후 해당 컬럼에 해당하는 값을 보여준다.
  • NaN은 제외하고 계산된다.
df_copy.groupby('group').mean(numeric_only=True)
group height brand
뉴진스 166.04 3082933.2
레드벨벳 164.50 1786140.5
방탄소년단 178.40 3858656.0
블랙핑크 165.00 2024410.5
소녀시대 168.00 1982581.5
워너원 180.50 1830385.5
blood gender height brand
A 남자 179.000 3.560683e+06
  여자 165.400 2.371581e+06
AB 남자 179.000 3.470048e+06
B 여자 165.875 2.004014e+06
O 남자 179.000 1.680587e+06
  여자 165.850 3.231469e+06
  • 위처럼 group을 통해 여러 값을 한번에 분석할 수도 있다.

중복값 제거

# drop_duplicates(): 중복된 데이터를 제거
df_copy['blood'].drop_duplicates()
  • 중복된 데이터를 제거해준다.
df_copy['blood'].drop_duplicates(keep='last')

# 4      AB
# 5     NaN
# 15      B
# 18      A
# 19      O
# Name: blood, dtype: object
  • 어떤 인덱스가 남았는지 표시해준다.
df_copy['company'].value_counts()

# company
# 빅히트     7
# 어도어     5
# 와이지     4
# 에스엠     2
# 판타지오    1
# Name: count, dtype: int64
df_copy['company'].value_counts(dropna=False) # NaN를 포함
  • 이건 데이터 value값의 개수를 읽어오는 일을 한다.

데이터 프레임 합치기

df1 = pd.read_csv('idol.csv')
df2 = pd.read_csv('idol2.csv')

df_copy = df1.copy()

pd.concat([df1, df_copy])# axis=0 (기본값)
  • 기본값이 0이기 때문에 행으로 추가된다.
      이름 그룹 소속사 성별 생년월일 혈액형
    0 지민 방탄소년단 빅히트 남자 1995-10-13 174.0 A
    1 정국 방탄소년단 빅히트 남자 1997-09-01 179.0 A
    2 민지 뉴진스 어도어 여자 2004-05-07 169.0 A
    3 하니 뉴진스 어도어 여자 2004-10-06 161.7 O
    생략              
    0 지민 방탄소년단 빅히트 남자 1995-10-13 174.0 A
    1 정국 방탄소년단 빅히트 남자 1997-09-01 179.0 A
    2 민지 뉴진스 어도어 여자 2004-05-07 169.0 A
    3 하니 뉴진스 어도어 여자 2004-10-06 161.7 O
    4 방탄소년단 빅히트 남자 1995-12-30 179.0 AB
    5 다니엘 뉴진스 어도어 여자 2005-04-11 165.0 NaN
    6 혜인 뉴진스 어도어 여자 2008-04-21 170.0 O
  • 위처럼 두개의 csv파일이 합쳐지는데 index가 연속적으로 붙어나오는 것을 알 수 있다. 이걸 해결하렴ㄴ
df_concat = pd.concat([df1, df_copy])

# reset_index(): index를 새롭게 적용
# drop=True 옵션을 사용하여 기존 index가 컬럼으로 만들어지는 것을 방지
df_concat.reset_index(drop=True)
  • 위처럼 reset_index를 통해 index를 새로 만들어줄 수 있다
  • drop=true가 없으면 원래 인덱스가 새로운 컬럼으로 추가되는데, 이걸 넣어 원래 인덱스를 없애준다.
pd.concat([df1, df2], axis=1) # 같은 index와 결합
  • 열을 통해 결합시켜준다.

merge 메서드

df_right = df2.drop([1, 3, 5, 7, 9], axis=0)
df_right = df_right.reset_index(drop=True)
df_right
  • 만약 일부 컬럼을 제거하고, index를 리셋해줄 경우에
  • 이름이 같더라도 아무런데나 붙어 데이터가 고장날 것이다.

이때 merge를 사용할 수 있다.

df1 = pd.read_csv('idol.csv')

# merge(): 특정 고유한 키(unique, id)값을 기준으로 합침
# merge(데이터프레임1, 데이터프레임2, on='유니크값', how='병합의 기준')
# 병합의 기준: left, right, inner, cross
pd.merge(df1, df_right, on='이름', how='left')
  • on은 기준이 될 컬럼명
  • how는 left, right, cross, inner 등등을 정해줄 수 있다.(rdbms의 join과 같은 내용)

left는 왼쪽에 있는 값, inner는 둘다 있는 값, cross는 모든 경우의 수를 출력한다.

등수매기기

# rank(): 데이터프레임 또는 시리즈의 순위를 매기는 함수. 기본값은 ascending
df1['브랜드순위'] = df1['브랜드평판지수'].rank([ascending=False])
df1

rank를 통해 해당 값의 순위를 매겨줄 수 있다.

  • 위 코드는 브랜드 순위라는 컬럼을 만들어 준후 rank를 넣어줌
  • ascending을 통해 내림차순으로 만들어줄 수도 있다.
  • 기본 float로 나오지만 astype함수로 int로 만들어줄 수 있다.
# astype(): 특정열의 자료형을 변경
df1['브랜드순위'] = df1['브랜드순위'].astype(int)
df1

날짜 타입 사용하기

# to_datatime(): object타입에서 datetime타입으로 변환
df_copy['birthday'] = pd.to_datetime(df_copy['birthday'])
print(type(df_copy['birthday']))
print(df_copy['birthday'].dtypes)

위의 object메소드였던 birthday를 datetime자료형으로 변환해준다.

df_copy['birthday'].dt.year #년 출력
df_copy['birthday'].dt.month #월 출력
df_copy['birthday'].dt.day #일출력
df_copy['birthday'].dt.hour #시간 출력
df_copy['birthday'].dt.minute #분 출력
df_copy['birthday'].dt.second #초 출력
df_copy['birthday'].dt.dayofweek # 요일: 0(월요일) ~ 6(일요일)df_copy['birthday'].dt.isocalendar().week
df_copy['birthday'].dt.isocalendar().week #해당 날짜가 몇주차인가?

apply함수

데이터 프레임이나 시리즈의 데이터를 사용자 정의 함수, 내장함수에 적용하여 새로운 값을 계산하거나 변환할 때 사용됩니다.

def male_or_female(x):
    if x == '남자':
        return 1
    elif x == '여자':
        return 0
    else:
        return None
  • 위 함수는 남자가 들어오면 1 리턴, 여자가 들어오면 0 리턴, 잘못 들어오면 None을 리턴하는 값이다.
df_copy['gender'].apply(male_or_female)

만약 해당 값으로 컬럼을 만들고자 한다면 apply를 사용해

def male_or_female(x):
    if x == '남자':
        return 1
    elif x == '여자':
        return 0
    else:
        return None

df_copy['gender'].apply(male_or_female)

# 0     1
# 1     1
# 2     0
# 3     0
# 4     1
# 5     0
# 6     0
# 7     0
# 8     0
# 9     0
# 10    1
# 11    0
# 12    1
# 13    0
# 14    0
# 15    0
# 16    0
# 17    0
# 18    1
# 19    1
# Name: gender, dtype: int64

위처럼 값을 변환 해줄 수 있다.

그러나 해당 함수를 간단하게 만들어주려면

df_copy['gender'].apply(lambda x: 1 if x == '남자' else 0)
  • 람다식으로 true는 1 남자가 아니면 0을 출력하도록 만들 수 있다.

해당 apply함수는 피처 엔지니어링 시 데이터 값을 숫자로 변환시켜 줄 때 주로 사용한다.

더 간단하게 map으로 사용하기

map_gender = {'남자':1, '여자':0}

df_copy['gender'].map(map_gender)

# 0     1
# 1     1
# 2     0
# 3     0
# 4     1
# 5     0
# 6     0
# 7     0
# 8     0
# 9     0
# 10    1
# 11    0
# 12    1
# 13    0
# 14    0
# 15    0
# 16    0
# 17    0
# 18    1
# 19    1
# Name: gender, dtype: int64
  • map을 통해 딕셔너리로 지정해둔 값을 빠르게 숫자로 만들어줄 수 있다.
  • 원래값 : 데이터값

산술연산

df1 = pd.DataFrame({
    '파이썬':[60, 70, 80, 90, 95],
    '데이터분석':[40, 60, 70, 55, 87],
    '머신러닝딥러닝':[35, 40, 30, 70, 55]
})
total = df1['파이썬'] + df1['데이터분석'] + df1['머신러닝딥러닝']

# 0    135
# 1    170
# 2    180
# 3    215
# 4    237
# dtype: int64

만약 게산시 NaN이 껴 있었다면 NaN이 결과값으로 보낸다.

Get_dummies(원핫 인코딩)

데이터의 종류는 위와 같다

범주형 데이터 판단 기준

데이터 분석, 머신러닝 모델을 만들 때 컬럼을 범주형 데이터로 변환할 지 삭제해야할지 판단해야한다.

  • 실제 데이터는 숫자처럼 보이나, 의미가 없기도 하고,
    • 명목형을 컴퓨터에 인지시키기 위해 숫자로 데이터를 넣어주는데 이걸 순서가 있는 숫자로 인식할 가능성도 존재한다.
  • 범주형으로 처리하지 않으면 분석결과가 왜곡되기도 한다.

기준

  1. 값의 종류가 적고 의미있는 그룹을 형성할 때
    • 성별, 지역, 직급, 날씨등
    • 그룹분석이 가능하고, 평균·합계를 내는 것보다 범주별 비교가 더 의미 있는 케이스입니다.
  2. 숫자처럼 보이지만 수학적으로 의미가 없을 때
    • 회원번호, 상품코드, 우편번호, 전화번호등
    • 겉으로는 숫자처럼 보이나, 산술적 연산이 의미가 없는 것들
  3. 머신러닝 입력을 위해 인코딩이 필요한 경우
    • color, 브라우저등
    • 머신러닝은 문자열을 직접 다루지 못하므로 범주형으로 변환한 뒤 원핫 인코딩 또는 레이블 인코딩을 적용한다.
  4. 연속 값이지만 범주로 나누는 것이 더 의미가 있을때
    • 나이(10대, 20대, 30대), 매출(고,중,저), 위험등급(Low, Medium,High)
      • 상세하게 보는 게 의미가 없는 경우.
    • 이처럼 의미있는 구간을 만들어 카테고리화하면 분석 인사이트가 더 명확해진다.

제거할 컬럼 기준

  1. 고유값이 너무 많아 패턴이 없는 경우
    • 주문번호, 주민번호, UUID, 세션ID등 패턴이 없는 경우
  2. 지나치게 상세한 정보(과도한 해상도)
    • 초 단위로 들어가 있는 timestamp, 도로명+상세주소 등
    • 정보는 많지만 의미있는 패턴을 제공하지 않으므로 가공해야한다
      • 시간: year, month, hour, weekday등으로 분리
      • 주소: 시, 구 단위
  3. 결측치가 지나치게 많은 것.
    • ex) 전체의 80% 이상이 null
    • 대부분의 경우 해당 컬럼은 과감히 삭제하는 것이 중요

원 핫 인코딩

원-핫 인코딩은 각 범주를 별도의 열로 변환하고, 해당 범주에 해당하는 곳에 1을 나머지에 0을 채우는 방식

  • red = 1 0 0, blue = 0 1 0, green = 0 0 1
df = pd.get_dummies(df, columns=['혈액형'])
  이름 중략 혈액형_A 혈액형_AB 혈액형_B 혈액형_O
0 지민 True False False False
1 정국 True False False False
2 민지 True False False False
3 하니 False False False True
4 False True False False

레이블 인코딩(라벨인코딩)

각 데이터를 하나의 숫자로 연결시켜주는 작업

  • red, green, blue: red=0, green=1, blue=2

'AI공부 > 머신러닝' 카테고리의 다른 글

5. selenium을 이용한 크롤링  (1) 2025.11.26
4. 공공 데이터셋 가져오기  (0) 2025.11.26
참고) 머신러닝/딥러닝 모델별 장단점 표  (0) 2025.11.25
3. matplot  (0) 2025.11.19
1. numpy  (0) 2025.11.12