[python]_pandas_데이터전처리(표준화 등)

Hi K·2022년 11월 1일
0

pandas

목록 보기
5/5
코드를 입력하세요
# 데이터 전처리
- 데이터 형식에 대한 처리
    - 공백 문자
        - str.strip() : 양쪽 공백 제거
        - str.lstrip() : 왼쪽 공백 제거
        - str.rstip() : 오른쪽 공백 제거
    - 데이터 타입
    - 불규칙한 대소문자
    - 불규칙한 구분기호
    - 유효하지 않은 문자
    - 불규칙한 날짜 및 시간 표기
    
 # 라이브러리 불러오기
import pandas as pd
import numpy as np

1. 날짜형식

# 날짜 데이터1 : str타입
str_date = ['2022/11/01', '2022.10.31','2021-10-09']

# 시리즈 형태로 저장
pd.Series(str_date)

# 1)str 타입을 datetime 타입으로 변환후 pandas 저장
# pd.to_datetime()
pd.Series(pd.to_datetime(str_date))

# 2) str 타입으로 저장 후 데이터 타입 변경
# series.dtype : 데이터타입 확인
# series.astype() : 데이터타입 변경
pd.Series(str_date).astype('datetime64')

# 날짜 데이터 2 : timestamp 타입
# timestamp : 기준시각( 1970. 01. 01 00:00:00 UTC)로부터 몇 초가 경과했는지 표기
# (unix 시간)
stamp_date = [1234000, 1234101, 1234202, 1234300, 1234500 ]

pd.Series(stamp_date)

# datetime 타입으로 변환 후 저장
# timestamp의 기본 unit = ns(nano seconds) 나노초 : 10억분의 1초
# unit = ns(default), D(days), s(second), ms(milli seconds), us(micro seconds)
pd.Series(pd.to_datetime(stamp_date))

# unit = s(seconds)
pd.Series(pd.to_datetime(stamp_date, unit='s'))

# unit = D
pd.Series(pd.to_datetime(stamp_date, unit='D')) # 에러남

# unit = ms
pd.Series(pd.to_datetime(stamp_date, unit='ms'))

# unit = us
pd.Series(pd.to_datetime(stamp_date, unit='us'))

2. 라벨 형식 통일

  • 데이터의 인코딩 작업에 포함
# map()
# dictionary 타입으로 encoding map을 생성해서 적용
# gender = 0(남자), 1(여자)
df = pd.DataFrame({'gender':[0, 0, 0, 1, 0, 1]})
gender_map = {0:'M', 1:'F'}
df

# df 변수의 'gender'컬럼의 값을 map 함수를 이용해 0은 M으로, 1은 F으로 변환
df['gender'].map(gender_map)

# 기존에 배운 파이썬 기본 문법으로 바꾸기
# 찾아 바꾸기인 replace()를 써도 됩니다
# 여러분들이 아래 코드를 이용해 M,F로 바뀐 df를 저장해주세요.
df = pd.DataFrame(df['gender'].replace(0, 'M').replace(1, 'F'))
# df['gender'] = df['gender'].replace([0,1], ['M'.'F'])
# df['gender'] = df['gender'].replace({0:'M'}, {1:'F'}) #에러
df

3. 문자 형식(대소문자, 기호 등) 통일

data = {'Name': ['Jane','Albert','John'],
       'Age':[18, 19, 20]}
df1 = pd.DataFrame(data)
df1

# 컬럼명을 소문자로 바꾸는 첫 번째 방법
# 빈 리스트에 소문자로 변경한 컬럼을 모두 적재한 뒤 대입
new_cols = list() #[]
for col in df1.columns:
    print(col.lower())
    new_cols.append(col.lower())
    
new_cols
df1.columns = new_cols
df1

# df.columns.str에 바로 upper() 등을 걸 수 있음
df1.columns.str.upper()

# 위 코드를 이용해 대문자로 교체해주세요.
df1.columns = df1.columns.str.upper()
df1

# 내부 요소(NAME 컬럼) 의 모든 자료를 소문자로 통일
# age : 정수 자료이므로 고칠 필요가 없음. 따라서 배제.
# .apply(함수명)
# 해당 함수의 리턴값으로 컬럼 내부 값을 일괄적으로 교체해주는 명령어
def change_lower(value):
    return value.lower()
    
df1['NAME'].apply(change_lower)
# change_lower함수를 적용해서 NAME컬럼의 값을 소문자로 바꿔주었다

# apply는 map으로 대체 가능합니다.
df1['NAME'].map(change_lower)

# AGE 컬럼의 값을 20이상이면 "성인", 19이하면 "미성년자"
# 를 리턴하도록 is_adult() 함수를 아래에 정의해주시고
def is_adult(value):
    if value >= 20:
        value = "성인"
    else:
        value = "미성년자"
    return value
    
    
# 위 함수를 .apply()로 활용해 값을 일괄적으로 변경해주세요.
df1['AGE'] = df1['AGE'].apply(is_adult)
df1

데이터 값에 대한 처리

  • 결측값(NaN)
  • 이상치(예측한 범위 밖의 값)
  • 단순 중복 데이터
  • 동일한 의미, 다른 명칭의 중복 데이터
  • 중복속성(다중공선성)
  • 불규칙한 데이터 수집(간격, 단위)
# 데이터 적재
sample = pd.read_csv('data/data/csv_exam_nan.csv')
sample

>결측치 처리 - 삭제

  • 결측치가 하나라도 있는 레코드 삭제
  • 모든 값이 결측인 레코드 삭제
  • 결측치가 하나라도 있는 데이터만 선택
# 결측치가 하나 이상인 레코드(row) 삭제
# df.dropna(how= 'any'(default), inplace=True)
# inplace 파라미터 : 원본에 바로 반영
sample.dropna() # how='any'

# 모든 값이 결측치인 레코드만 삭제
# df.dropna(how='all')
sample.dropna(how='all')

# 결측치가 하나라도 있는 데이터만 선택
# 조건색인으로 처리한 것이고, isnull().any()의 원리를 이해해주세요.
# df[df.isnull().any(axis=1)]
sample[sample.isnull().any(axis=1)]

# isnull()은 모든 셀을 구분해서 NaN가 있는 셀은 True, 아닌 셀은 False를 출력합니다.
sample.isnull()

# any는 해당 컬럼에 isnull()의 결과값이 True인 셀이 존재하는지 체크해줍니다.
# 디폴트는 axis=0(컬럼기준으로 결측치 있음, 없음 여부 조사)
sample.isnull().any()

# axis=1 을 기입하면 볓 번 row에 결측치가 있고, 몇 번에 없는지 True, False로 보여줍니다.
sample.isnull().any(axis=1)

# 조건색인으로 NaN가 포함된 행을 보여준다
sample[sample.isnull().any(axis=1)]

# 결측치 개수를 세는 법
sample.isnull().sum()

>결측치 처리 - 대체값

  • 연속형 : 임의값(0...등), mean, median, 예측값, 도메인지식 활용(((숫자)))
  • 명목형 : mode(최빈값), 예측값, 도메인지식 활용(((문자)))
# mean 반 키 평균값 구할때
# median 정봉준 국회의원 
# 최빈값 : 성비비율 여자/남자
# 예측값 :값을 예측해서 직접 넣어줌
# 도메인지식

# 연속형 - 임의의 값으로 대체
# df.fillna(v)
sample.fillna(0)

# df.values.mean() : Array타입의 연산으로 NaN값이 하나라도 있다면 최종결과도 NaN
# sample.values.mean() -> 전체 평균을 구할 수 있지만 NaN
# df.fillna(0) 으로 결측치를 보완하고 => mean()평균을 구해야 함
# NaN가 0으로 대체된 평균을 먼저 구한다음, 그 평균값으로 결측치를 메꿔주세요
# mean1 = sample.fillna(0).mean() >>>과목별 평균이 구해짐
# sample.fillna(mean1)
tot_avg = sample.fillna(0).values.mean()
sample.fillna(tot_avg)

# mean - 2) 결측치가 존재하는 속성(변수 = 컬럼)의 평균값
# sample : math/en/sc 컬럼에 존재하는 결측치 -> math/en/sc 컬럼의 평균값
# df.mean() : 컬럼별 평균
# 인덱싱으로 과목별 평균 조회
print(sample.mean()[0])
print(sample.mean()[1])
print(sample.mean()[2])

# 컬럼 지정 후 평균 구하기
sample['math'].mean()

# fillna를 이용해 수학, 영어, 과학 컬럼에 각각 컬럼의 평균값을 결측치 대신 넣어보세요
sample['math'] = sample['math'].fillna(sample.mean()[0])
sample['english'] = sample['english'].fillna(sample.mean()[1])
sample['science'] = sample['science'].fillna(sample.mean()[2])
# sample['science'].fillna(sample['science'].mean())
sample

# 데이터 적재
sample = pd.read_csv('data/data/csv_exam_nan.csv')
sample

# median - 전체 데이터에 대한 중위값
# tot_avg : 54.5
# median() 을 이용해 몇인지 구해서 1:1로 보내주세요.
# Series나 DataFrame은 벡터함수 연산시 자동으로 NaN를 배제합니다
# 따라서 전체데이터의 중위값을 구하기 위해 먼저 Series로 바꿔줍니다.
# sample.size를 .reshape()에 넣어주면 자동으로 1차원배열로 크기 맞춰서 바꿔줍니다
tot_med = pd.Series(sample.values.reshape(sample.size)).median()
sample.fillna(tot_med)

# mode - 범주형 데이터에서는 최빈값을 사용
# describe()
# value_counts()
# collections 라이브러리의 Counter 모듈
df = pd.DataFrame({'label':['A','B','B','C','C','C','D']})
df

df.describe()
# describe는 통계분석에 사용합니다
# count : 컬럼의 총 데이터의 개수
# unique : 데이터 유형의 개수
# top : 가장 많이 나온 요소
# freq : top의 빈도수

df.describe().loc['top']

# Series로 변경하기 위해 label 컬럼을 지정한 후, value_counts()를 이용해
# 각 범주별 개수를 구할 수 있음
df['label'].value_counts()

from collections import Counter
# 1. 라이브러리를 가져오기
# 2. Counter()를 이용해 Counter 타입의 자료 생성
# 3. counter객체.most_common() =>[(value1, count1), (value2, count2) ...]

colors = ['red','blue','pink','blue','blue','red']
counter = Counter(colors)
counter

# most_common()
# 갯수순으로 나열해줌
counter.most_common()

# 데이터프레임에도 Counter를 쓸 수 있습니다
df = pd.DataFrame({'label': ['A','B','B','C','C','C','D']})
df

Counter(df['label']).most_common()

데이터 단위 통일

표준화(Standardization)

  • 평균을 기준으로 얼마나 떨어져 있는지를 파악
  • sklearn에서 제공하는 전처리 클래스
    • preprocessing 클래스
      • scaler() : 전체 자료의 분포를 평균 0, 표준편차 1이 되도록 스케일링
      • minmax_scale() : 최대/최소값이 각각 1, 0이 되도록 스케일링
      • StandardScaler() : scaler() 함수와 동일한 동작
  • 표준화 : (요소값(하나의 데이터) - 평균) / 표준편차
  • 삼성전자 vs 작은회사 주식 시세
  • 몸무게 vs 키
    • 표준화 결과 : 몸무게 음수, 키 양수
    • 해석 : 몸무게는 평균 이하, 키는 평균 이상(=>마른몸)
# 전처리 기능을 제공하는 scikitlearn 라이브러리 및 모듈 가져오기
from sklearn.preprocessing import scale, minmax_scale

# -3이상, 5 이하의 정수를 값으로 가지는 9행 1열 배열 생성
# np.arange(9)에 스칼라값으로 -3 빼줌
x = (np.arange(9)-3).reshape(-1,1)
x

# 데이터프레임 생성
# 3개 컬럼 : x, scale(x), minmax_scale(x)
type(x)

scale(x)

# np.hstack =>가로방향으로 붙여줌
# np.vstack =>세로방향으로 붙여줌
# 9 * 1 데이터 3개를 가로로 붙여서 9 * 3으로 (세로로 붙였으면 27 * 1)만들고
# 붙여준 컬럼별로 수행한 연산을 컬럼명으로 정의

df = pd.DataFrame(np.hstack([x, scale(x), minmax_scale(x)]),
                 columns=['x','scale(x)','minmax_scale(x)']
df
profile
파이썬초짜의 기록

0개의 댓글