본문 바로가기
빅데이터분석

[파이썬] 파이썬 입문 데이터분석 프로젝트 만들기 - (16) 결측치(NA, NaN, None) 처리하기

by 모닥불🔥 2024. 5. 29.

사진을 클릭하면 링고선생님의 파이썬 데이터분석 프로젝트 강의를 수강할 수 있다.

이번 글 내용은 강의자료 3-10에 속한다. 결측치(NA)가 있는지 확인하고, 삭제 또는 대체하는 부분은 빅분기 실기에서도 나오고, 실제 프로젝트에서도 정말 많이 사용되기 때문에 반드시 이해해야 한다.


🔥 강의 목차

오리엔테이션
파이썬 기초 문법
데이터 전처리
데이터 시각화
마케팅 데이터 분석 및 지표 정의하기

🔥 결측치(NA/NaN/None)

데이터를 모으다 보면, 누락된 데이터가 생긴다. NA는 누락된 데이터(결측치)를 나타내는 일반적인 용어이다. 결측치를 표현하는 비슷한 용어 3종이 있는데, 참고로 알아두자. 그냥 다 결측치라고 퉁쳐서 생각해도 상관은 없을 듯..

  • NA: 일반적인 결측치를 의미
  • NaN: 부동소수점(float) 데이터셋에서 누락된 값을 의미
  • None: 객체 타입(object)에서 '값이 없음'을 의미

(1) 결측치

import pandas as pd
import numpy as np

data = {'숫자열': [1, 2, None, 4,None],
        '문자열': ['사과', None, '바나나', '체리','']}

df = pd.DataFrame(data)
df

 

데이터프레임을 만들 때 None이라고 똑같이 입력하더라도, 위와 같이 float 타입의 데이터에서는 NaN으로, object 타입의 데이터에서는 None으로 표시됨을 알 수 있다.

또한, 결측치와 '' 와 같은 공백 문자는 다르다. 따옴표 안에 아무 값을 넣지 않더라도 None은 아님!

 

(2) df.isna(): 결측치인지 아닌지 확인

결측치인지 아닌지 알아보는 방법은 df.isna() 를 출력해보는 것이다. is na?(결측치인가요?) 라고 묻는다고 생각하면 된다. "네 결측치예요" 라는 의미의 True, 혹은 "아니오 결측치가 아닙니다" 라는 의미의 False로 표시된다.

df.isna() # '결측치인가요?' -> 네(True)/아니오(False)

 

(3) dropna(): 결측치가 포함된 행 제거

결측치가 발견되면 어떻게 처리할 수 있을까? 원하는 값으로 바꾸거나 결측치가 있는 행을 삭제할 수 있다.

결측치가 포함된 행을 삭제할 때 dropna()를 사용하는데, 이때 how 매개변수에는 any/all을 사용하여 원하는 설정을 할 수 있다. how 매개변수를 따로 입력하지 않으면 how = 'any'가 디폴트값이다.

how = 'any': 결측치가 하나라도 있으면 행을 제거(기본설정)

how = 'all': 모든 값이 결측치인 행만 제거

dropna(subset=['col_1','col_2',...], how = 'any/all')

 

아래 코드로 예시 데이터를 생성해보자.

import pandas as pd
import numpy as np

# 샘플 데이터 프레임 생성
data = {'A': [1, None, 3, 4, None, None, 10],
        'B': [None, 2, 3, None, 5, None, 10],
        'C': [1, 2, None, 4, 5, None, 10 ]}

df = pd.DataFrame(data)

 

dropna() 옵션을 any 또는 디폴트로 하면 NaN이 하나라도 포함된 값을 모두 제거하여 온전한 행인 마지막 행만 남는다.

df.dropna()
df.dropna(how = 'any')

# 두 코드는 동일한 결과

 

dropna(how = 'all')을 하면 A, B, C 컬럼의 값이 모두 None인 index 5번 행만 제거된다.

df.dropna(how='all')

(4) fillna(): 결측치를 다른 값으로 대체

결측치가 포함된 행을 다른 값으로 대체할 수도 있다. 기본 형태는 아래와 같다. 딕셔너리 형태로 '대상 컬럼': 대체할 값을 입력하면 된다. inplace = True를 입력해야 데이터프레임에 반영되므로 주의할 것

df.fillna(
  {'col_1' : value1
  , 'col_2' : value2}
  , inplace = True
)

 

예시 데이터를 다시 생성하고,

# drop na df
import pandas as pd
import numpy as np

# 샘플 데이터 프레임 생성
data = {'A': [1, None, 3, 4, None, None, 10],
        'B': [None, 2, 3, None, 5, None, 10],
        'C': [1, 2, None, 4, 5, None, 10 ]}

df = pd.DataFrame(data)

 

전체 결측치를 한 번에 처리할 때는 딕셔너리 형태로 쓰지 않고, 그냥 대체값, inplace = True 만 적어도 된다.

A, B, C 컬럼의 모든 결측치가 0.0으로 대체된 것을 확인할 수 있다.

df.fillna(0, inplace = True) # null을 0으로 채움
df

 

(실습 시에는 예시 데이터를 다시 불러올 것)

컬럼별로 결측치를 각각 다른 값으로 대체하고 싶다면, 아래와 같이 코드를 적는다.

A의 결측치는 100, B의 결측치는 1000, C의 결측치는 10000으로 변경된 것을 확인할 수 있다.

df.fillna({
    'A': 100,
    'B': 1000,
    'C': 10000
}) # A, B, C 각각 널일 때 100, 1000, 10000

 

(실습 시에는 예시 데이터를 다시 불러올 것)

대체할 값을 구해서 대체할 수도 있다. A는 평균대체, B는 합계값으로 대체, C는 최대값으로 대체해보자.

df.fillna({
    'A': df['A'].mean(),    # null이면 평균대체
    'B': df['B'].sum(),     # null이면 합계로 대체
    'C': df['C'].max()      # null이면 최대값 대체
}
)

 

 

* 본 게시글은 '메타코드'의 동의를 받아 작성된 글로, 강의 내용에 대한 모든 저작권은 Ringo 선생님에게 있습니다. 개인용도의 학습 외에 무단사용은 엄격히 금지됩니다. 위반 시 법적 조취가 취해질 수 있습니다.