[ProDS] 데이터 전처리 : 결측치, 이상치

Gammi·2022년 11월 23일
0

proDS

목록 보기
7/13

✔ 이상치


  • 이상치 : 중심 경향성에서 멀리 떨어진 값



✔ 결측치


  • 값이 기록되지 않고 비어있음

  • 단순 제거 or 특정 값으로 대체


import pandas as pd
ir = pd.read_csv("iris_missing.csv")
# 파일 불러오기




📚 주요 함수


📕 isna()


  • 결측치 원소를 True, 관측치(값이 있는 원소)를 False로 반환

  • 반대는 notna()


df_na = ir.head(7)
#head(n)는 차례대로 위에 있는 값 n개 보여줌

df_na["Sepal_Length"].isna()
# [] 안에 들어간 값은 열 이름
# 마지막만 True, 나머지 false 반환

df_na["Sepal_Length"].notna()
# Nan이 아니냐는 뜻이니까
# 마지막만 False, 나머지는 True 반환

🔗 참고

True = 1 , False = 0의 값을 가짐

df_na["Sepal_Length"].isna().sum()
# Nan 값 하나니까 1 출력됨
ir.isna().sum() 
# 컬럼 별(열) 결측치 개수 출력됨
ir.isna().sum().sum()
# 한 번 더 더해주면 전체 결측치 개수 출력됨
df_na.isna().sum(axis=1)
# 로우 기준(행) 결측치 개수 출력
# axis = 0 이 기본값인데 얘는 컬럼 기준 연산임
# 1로 해줘야 로우기준 연산함



📕 fillna()


  • 결측치를 채워넣기 위한 메서드

  • value 인자에 결측치를 채워 넣을 값 입력

  • 딕셔너리 사용 가능


df_na.fillna(value = {"Sepal_Length" : 999})
# 딕셔너리 사용
# Sepal_Length에 Nan 값에 999 채워짐

df_na.fillna(value = {"Sepal_Length" : 999,
                      "Sepal_Width" : 999})
# Sepal_Width에도 999 같이 채워짐

df_na.fillna(value = 999)
# 딕셔너리 사용 안함
# 모든 Nan 값에 999 채워짐

⭐ 평균 값으로 채워넣기

df_na["Sepal_Length"].mean()
# 평균값 계산
# 결측치 빼고 계산해줌

df_na = df_na.fillna(value = {"Sepal_Length" : df_na["Sepal_Length"].mean()})
# 마지막에 덮어써야 적용됨



📕 dropna()


  • 결측치 있는 로우 또는 컬럼 제거

  • 보통 로우 기준

  • how 인자에 anyall 값 넣어서 제거

    -> any : 결측치가 하나라도 있는 경우

    -> all : 전체가 결측인 경우


df_na.dropna()
# 7개 행 뽑았는데 3개의 행만 남음
# 결측치 하나라도 있으면 다 날려버려서

df_na.dropna(how = "all")
# 값 변하지 않고 그대로 출력됨
# 모두 결측치인 행 없음

df.na.iloc[:, :-1].dropna(how = "all")
# 처음부터 제일 마지막 컬럼 빼고 출력 
# 근데 how에 all 줘서 제일 마지막 행 삭제되고 나머지 행만 출력됨



📕 quantile()


  • 분위수 연산하는 메서드

  • 이상치 필터링에 활용

  • q 파라미터에 0~9의 확률값 입력해서 그에 맞는 분위수 산출 가능


pd_na["Sepal_Lenght"].quantile()
# 그냥 출력할 경우 중위수 출력됨
pd_na["Sepal_Lenght"].median()
# 중위수 출력하는 메서드, 위의 코드와 동일함

pd_na["Sepal_Lenght"].quantile(q = 0.25)
# 제1사분위수 출력





  1. 각 수치형 변수의 결측치 개수 총합은?
ir.iloc[:,:-1].isna().sum().sum()
# iloc[:, :-1]로 출력한 이유?
# 수치형 변수의 결측치만 출력하라고 해서
# 마지막 컬럼의 값은 수치형 아님


  1. Sepal_Width 변수의 결측치를 평균으로 대치한 값의 분산은?
ir["Sepal_Width"].fillna(value=(ir["Sepal_Width"].mean())).var()
# 분산 구할 때 var() 메서드 사용



  1. 평균을 기준으로 1.5 표준편차를 넘어서는 값을 이상치라고 간주할 때 Sepal.Length 변수를 기준으로 이상치인 row는 몇 개인가?
# 1.5 넘어가는 값이 이상치니까 1.5 빼고 다 이상치임
# 1.5 미만도 1.5 초과도...
# 두 개의 값 모두 구해서 더하기

ir = pd.read_csv("iris.csv")

ir_mean = ir["Sepal.Lenght"].mean() # 평균
ir_std = ir["Sepal.Lenght"].std() # 표준편차

count1 = ir["Sepal.Lenght"] < (ir_mean - 1.5 * ir_std)
# 평균 * 1.5보다 작은 값
count2 = ir["Sepal.Lenght"] > (ir_mean + 1.5 * ir_std)
# 평균 * 1.5보다 큰 값

count1.sum() + count2.sum()
# 21 나옴
# 나는 이렇게 했는데...

ir_out = ir.loc[(count1) | (count2)]
len(ir_out)
# 이 정석 방법...
# 파이썬은 | 이거 하나만 쓰네...
profile
개발자가 되었어요⭐️

0개의 댓글