Pandas 활용한 데이터 분석 입문(4) - 결측치의 이해, 처리

천호영·2021년 6월 22일
0

결측치의 이해

결측치, 누락값(missing data)는 Null, None, Na, NaN 등으로 표기됩니다.
수집의 오류, 기록의 누락, 미 응답 등 다양한 원인으로 결측 값이 발생합니다.
데이터 분석을 위한 데이터의 가공시에 결측 값이 발생하기도 합니다.

결측치는 언제 어디서든 생성될 수 있으므로 결측치를 처리하는 방법이 중요합니다.
이때, 데이터의 손실을 최소화하는 방향으로 결측치 처리를 해야합니다.

결측 값 처리 방법

  • 레코드 전체 삭제(List-wise deletion)
    결측 값이 하나 이상 포함된 데이터를 모두 제거하는 방법
  • 단일 값 삭제(Pairwise deletion)
    행 전체가 아닌 단일 값만 제거하는 방법
  • 단순 대체법(Simple Imputation)
    해당 변수의 나머지 값들의 대표값(mean,median, mode)으로 대체
  • 예측값 대체법(Predictive Imputation)
    통계, 머신러닝 등을 활용한 예측 모델 기반으로 도출한 예측값으로 대체

결측 값 처리는 데이터 전처리 단계 중 데이터 정제 단계에 해당합니다.
가능한 결측치 발생 원인을 분석하고, 그에 따른 적절한 결측치 처리 기법 선택이 필요합니다.


결측치의 처리 (1)

1) 데이터의 결측치 유무 확인하는 함수
2) 실제 결측치가 저장된 위치를 찾아 처리하는 함수

df.info()
  • 각 컬럼 별 non-null (결측치가 아닌 값) 값의 개수를 출력함
  • 전체 행의 개수에서 non-null 의 개수를 빼면 나머지가 결측치의 개수가 됨
df.isnull()
  • DataFrame 내 모든 데이터에서 NaN 값을 찾아 해당 위치에 True/False 로 반환
  • df.isna() 함수와 동일한 기능을 수행함
df.isnull().sum()
  • 각 컬럼 별 결측 값의 개수를 확인할 수 있음. 가장 많이 사용되는 방식.
  • 각 행에 따른 결측 값의 개수를 확인할 때는 axis=1 의 인자를 활용

<실습코드>

import pandas as pd
import numpy as np

# 실습 데이터 생성
df = pd.DataFrame(data = np.arange(18).reshape(6,3),
				  index = ['a','b','c','d','e','f'],
                  columns=['col1','col2','col3'])
                  
df['col4'] = pd.Series(data = [1.7, 1.2, 2.4], 
                       index = ['a','e','c'])
df.loc['c'] = None
print('Sample Data')
print(df)


'''
df.info() 함수로 결측치 유무 확인하기
'''
print('\n#1 Summary of DataFrame')
print(df.info())


'''
df.isnull() 함수로 결측치 유무 확인하기
'''
print('\n#2 isnull of DataFrame')
print(df.isnull())


'''
df.isnull().sum() 함수로 결측치 유무 확인하기
'''
print('\n#4 Sum of all missing values per columns')
print(df.isnull().sum())


'''
df.isnull().sum() 함수에서 데이터 집계 방향 바꾸기
'''
print('\n#5 Sum of all missing values per rows')
print(df.isnull().sum(axis=1))

<실행결과>

Sample Data
   col1  col2  col3  col4
a   0.0   1.0   2.0   1.7
b   3.0   4.0   5.0   NaN
c   NaN   NaN   NaN   NaN
d   9.0  10.0  11.0   NaN
e  12.0  13.0  14.0   1.2
f  15.0  16.0  17.0   NaN

#1 Summary of DataFrame
<class 'pandas.core.frame.DataFrame'>
Index: 6 entries, a to f
Data columns (total 4 columns):
 #   Column  Non-Null Count  Dtype  
---  ------  --------------  -----  
 0   col1    5 non-null      float64
 1   col2    5 non-null      float64
 2   col3    5 non-null      float64
 3   col4    2 non-null      float64
dtypes: float64(4)
memory usage: 412.0+ bytes
None

#2 isnull of DataFrame
    col1   col2   col3   col4
a  False  False  False  False
b  False  False  False   True
c   True   True   True   True
d  False  False  False   True
e  False  False  False  False
f  False  False  False   True

#4 Sum of all missing values per columns
col1    1
col2    1
col3    1
col4    4
dtype: int64

#5 Sum of all missing values per rows
a    0
b    1
c    4
d    1
e    0
f    1
dtype: int64

결측치의 처리 (2)

1) 데이터의 결측치 유무 확인하는 함수
2) 실제 결측치가 저장된 위치를 찾아 처리하는 함수

df.dropna()
  • 기본적으로 NaN 값이 하나라도 포함된 행 데이터를 조회 및 제거해주는 함수
  • 나머지 데이터를 DataFrame으로 반환함
  • Parameters
    how = ‘all’ : 모든 행 데이터의 값이 NaN 인 경우만 찾아서 제거함
    inplace=True : 원본 데이터에 적용
    axis=‘columns : dropna() 함수가 열을 기준으로 동작
  • 행 데이터 조회 및 제거 : axis=0 또는 axis='index'(기본값)
  • 열 데이터 조회 및 제거 : axis=1 또는 axis='columns'
    dropna는 집계함수가 아니므로 헷갈리면 안된다!
df.fillna(value)
  • 결측치를 다른 값으로 대체하는 함수로 인자 value 에 대체할 값을 입력함
  • value 값의 형식은 단일 값, 딕셔너리, Series, 또는 DataFrame 등이 될 수 있음
  • value 에 딕셔너리 객체 전달시 컬럼별 대체할 값을 다르게 설정할 수 있음
  • mean(), median(), mode() 등의 집계함수를 이용한 대표 값으로 결측값 대체 가능
  • 원본을 변경하기 위해서는 inplace=True 지정 필요

<실습코드>

import pandas as pd
import numpy as np

# 실습 데이터 생성
df = pd.DataFrame(data = np.arange(18).reshape(6,3),
				  index = ['a','b','c','d','e','f'],
                  columns=['col1','col2','col3'])
                  
df['col4'] = pd.Series(data = [1.7, 1.2, 2.4], 
                       index = ['a','e','c'])
df.loc['c'] = None
print('Sample Data')
print(df)

 
'''
1) 행을 기준으로 결측치 조회하여 제거하기
2) how=all 인자로 전체 nan 인 경우만 제거하기
'''
print('\n#1 Remove missing values')
print(df.dropna(how='all'))


'''
원본 데이터에 반영하기
'''
print('\n#2 Remove missing values with inpalce=True')
df.dropna(how='all', inplace=True)
print(df)

 
'''
열을 기준으로 결측치 조회하여 제거하기
'''
print('\n#3 Remove missing values in columns')
print(df.dropna(axis='columns'))

 
'''
실습 데이터를 추가
'''
df.iloc[:2, 0] = np.nan
df.iloc[:4, 1] = np.nan
print('\nSample Data')
print(df)


'''
결측값을 0 으로 대체하기
'''
print('\n#4 Replace missing values')
print(df.fillna(0))


'''
딕셔너리를 활용한 컬럼별 대체값 지정하기
'''
print('\n#5 Replace missing values')
replace_set = {'col2':0,'col4':'100'}
print(df.fillna(replace_set))


'''
1)대표값인 평균을 활용하여 결측치 대체하기
2)원본 데이터에 반영하기
'''
print('\n#6 Replace missing values')
replace_set = {'col1':df['col1'].mean()}
df.fillna(replace_set, inplace=True)
print(df)

<실행결과>

Sample Data
   col1  col2  col3  col4
a   0.0   1.0   2.0   1.7
b   3.0   4.0   5.0   NaN
c   NaN   NaN   NaN   NaN
d   9.0  10.0  11.0   NaN
e  12.0  13.0  14.0   1.2
f  15.0  16.0  17.0   NaN

#1 Remove missing values
   col1  col2  col3  col4
a   0.0   1.0   2.0   1.7
b   3.0   4.0   5.0   NaN
d   9.0  10.0  11.0   NaN
e  12.0  13.0  14.0   1.2
f  15.0  16.0  17.0   NaN

#2 Remove missing values with inpalce=True
   col1  col2  col3  col4
a   0.0   1.0   2.0   1.7
b   3.0   4.0   5.0   NaN
d   9.0  10.0  11.0   NaN
e  12.0  13.0  14.0   1.2
f  15.0  16.0  17.0   NaN

#3 Remove missing values in columns
   col1  col2  col3
a   0.0   1.0   2.0
b   3.0   4.0   5.0
d   9.0  10.0  11.0
e  12.0  13.0  14.0
f  15.0  16.0  17.0

Sample Data
   col1  col2  col3  col4
a   NaN   NaN   2.0   1.7
b   NaN   NaN   5.0   NaN
d   9.0   NaN  11.0   NaN
e  12.0   NaN  14.0   1.2
f  15.0  16.0  17.0   NaN

#4 Replace missing values
   col1  col2  col3  col4
a   0.0   0.0   2.0   1.7
b   0.0   0.0   5.0   0.0
d   9.0   0.0  11.0   0.0
e  12.0   0.0  14.0   1.2
f  15.0  16.0  17.0   0.0

#5 Replace missing values
   col1  col2  col3 col4
a   NaN   0.0   2.0  1.7
b   NaN   0.0   5.0  100
d   9.0   0.0  11.0  100
e  12.0   0.0  14.0  1.2
f  15.0  16.0  17.0  100

#6 Replace missing values
   col1  col2  col3  col4
a  12.0   NaN   2.0   1.7
b  12.0   NaN   5.0   NaN
d   9.0   NaN  11.0   NaN
e  12.0   NaN  14.0   1.2
f  15.0  16.0  17.0   NaN

0개의 댓글