파이썬

 

 

 

 

 

1.  결측치

 

1-1. 임의의 결측치 만들기 :    numpy.nan

import pandas as pd
import numpy as np

df = pd.DataFrame({'sex' : ['M', 'F', np.nan, 'M', 'F'],
                   'score' : [5, 4, 3, 4, np.nan]})
print(df)
'''
   sex  score
0    M    5.0
1    F    4.0
2  NaN    3.0
3    M    4.0
4    F    NaN
'''

 

 

1-2. 결측치 확인

#nan은 아예 값이 없는 False 상태이므로 값을 연산할 수 없음
df['score'] + 1
'''
0    6.0
1    5.0
2    4.0
3    5.0
4    NaN
Name: score, dtype: float64
'''



#결측치 여부 파악 : pandas.isna() => True / False
pd.isna(df)
'''
     sex  score
0  False  False
1  False  False
2   True  False
3  False  False
4  False   True
'''



#결측치 갯수 파악
pd.isna(df).sum()
'''
sex      1
score    1
dtype: int64
'''

 

 

1-3. 결측치 제거

    결측치가 있는 모든 행 제거 :    DataFrame.dropna()
    결측치가 있는 특정 행 제거 :    DataFrame.dropna(subset='지정 열')

    inplace=True로 설정해야 원본 데이터에 적용.

df.dropna()
df.dropna(subset = 'score')



#결측치를 자동으로 배제하는 연산 함수1 : mean()  /  sum()
df['score'].mean()
df['score'].sum()



#결측치를 자동으로 배제하는 연산 함수2 : groupby()  /  agg()
#집단(그룹) 별 통계량
df.groupby('sex').agg(mean_score = ('score', 'mean'), sum_score = ('score', 'sum'))
'''
     mean_score  sum_score
sex                       
F           4.0        4.0
M           4.5        9.0
'''

 

 

1-4. 결측치 대체 :    DataFrame.fillna()

exam = pd.read_csv('./data/exam.csv')

#임의의 record에 결측값 삽입
exam['math'].loc[[2, 7, 14]] = np.nan



#특정 열 전체 값의 평균
exam['math'].mean()
'''
55.23529411764706
'''



#해당 열 전체 값 평균으로 결측치 대체
exam['math'] = exam['math'].fillna(55)



#결측 여부 파악 시 결측 없음
exam['math'].isna().sum()
'''
0
'''

 

 

 

2. 이상치 : 존재할 수 없는 값

2-1. 이상치 확인 :    DataFrame.value_counts()

  DataFrame.value_counts()로 각 record의 값이 몇개나 존재하는지, 빈도 파악.

df = pd.DataFrame({'sex' : [1, 2, 1, 3, 2, 1],
                   'score' : [5, 4, 3, 4, 2, 6]})



df['sex'].value_counts(sort = False).sort_index()
'''
sex
1    3
2    2
3    1
Name: count, dtype: int64
'''
 
 
 
df['score'].value_counts(sort = False).sort_index()
'''
score
2    1
3    1
4    2
5    1
6    1
Name: count, dtype: int64
'''

 

 

2-2. 이상치를 결측치로 변경 :    numpy.where()

    if문 대체하여 사용하고, numpy.where()는 문자와 NaN을 함께 반환 못하므로 주의.

    구조 :    numpy.where(특정열의값이어떠하면, 어떤값을, 어떤열에넣음)

#sex가 3이면 NaN 부여
df['sex'] = np.where(df['sex'] == 3, np.nan, df['sex'])
'''
0    1.0
1    2.0
2    1.0
3    NaN
4    2.0
5    1.0
Name: sex, dtype: float64
'''



#score가 5보다 크면 NaN 부여
df['score'] = np.where(df['score'] > 5, np.nan, df['score'])
'''
0    5.0
1    4.0
2    3.0
3    4.0
4    2.0
5    NaN
Name: score, dtype: float64
'''



#sex, score 결측치 제거
#sex 별 분리 및 score 평균 산출
df.dropna().groupby('sex').agg(mean_score = ('score', 'mean'))
df.dropna(subset = ['sex', 'score']).groupby('sex').agg(mean_score = ('score', 'mean'))
'''
     mean_score
sex            
1.0         4.0
2.0         3.0
'''

 

 

2-3. boxplot을 이용한 이상치 확인 및 제거

1) boxplot으로 이상치 확인

mpg = pd.read_csv('./data/mpg.csv')

import matplotlib.pyplot as plt
import seaborn as sns

sns.boxplot(data = mpg, y ='hwy')
plt.show()

    이상치가 상단에 두개의 점으로 표시됨.

 

2) 극단치 산출하여 제거

#극단치 기준값 산출
#1. 1사분위수, 3사분위수 사용
pct25 = mpg['hwy'].quantile(.25)    #18.0
pct75 = mpg['hwy'].quantile(.75)    #27.0

#2. IQR 구하기 : 1사분위수, 3사분위수의 거리
iqr = pct75 - pct25    #9.0

#3. 극단 경계 구하기 : 하한, 상한 구하기
#하한 : 1사분위수 보다 IQR의 1.5배 만큼 더 작은 값
pct25 - 1.5 * iqr    #4.5
#상한 : 3사분위수 보다 IQR의 1.5배 만큼 더 큰 값
pc75 + 1.5 * iqr    #40.5



#극단치 결측으로 처리
mpg['hwy'] = np.where((mpg['hwy'] < 4.5) | (mpg['hwy'] > 40.5), np.nan, mpg['hwy'])
'''
0      29.0
1      29.0
2      31.0
3      30.0
4      26.0

229    28.0
230    29.0
231    26.0
232    26.0
233    26.0
Name: hwy, Length: 234, dtype: float64
'''



#결측치 갯수 파악
mpg['hwy'].isna().sum()
'''
3
'''


#hwy 결측치 제거 : drv별 분리 및 hwy평균 구하기
mpg.dropna(subset='hwy').gorupby('drv').agg('hwy')
'''
      mean_hwy
drv           
4    19.174757
f    27.728155
r    21.000000
'''



sns.boxplot(data = mpg, y ='hwy')
plt.show()

+ Recent posts