Data cleansing :: Data Problems
Data quality problems
- 데이터의 최대/최소가 다름 -> scale에 따른 y값에 영향 미침
- Ordinary 또는 Nominal한 값들의 표현은 어떻게 하나?
- 잘못 기입된 값들에 대한 처리
- 값이 없을 경우에는?
- 극단적으로 큰 값 또는 작은 값들을 그대로 나둬야 하는가?
Data preprocessing issues
- 데이터가 빠진 경우 (결측치의 처리)
- 라벨링 된 데이터 (category) 데이터의 처리
- 데이터의 scale의 차이가 매우 크게 날 경우
Data cleansing :: Missing Values
데이터가 없을 때 할 수 있는 전략
- 데이터가 없으면 sample을 drop
- 데이터가 없는 최소 개수를 정해서 sample을 drop
- 데이터가 거의 없는 feature는 feature 자체를 drop
- 최빈값, 평균값으로 비어있는 데이터를 채우기
Data drop
import pandas as pd
import numpy as np
raw_data = {'first_name': ['Jason', np.nan, 'Tina', 'Jake', 'Amy'],
'last_name': ['Miller', np.nan, 'Ali', 'Milner', 'Cooze'],
'age': [42, np.nan, 36, 24, 73],
'sex': ['m', np.nan, 'f', 'm', 'f'],
'preTestScore': [4, np.nan, np.nan, 2, 3],
'postTestScore': [25, np.nan, np.nan, 62, 70]}
df = pd.DataFrame(raw_data, columns = ['first_name', 'last_name', 'age', 'sex', 'preTestScore', 'postTestScore'])
df
|
first_name |
last_name |
age |
sex |
preTestScore |
postTestScore |
0 |
Jason |
Miller |
42.0 |
m |
4.0 |
25.0 |
1 |
NaN |
NaN |
NaN |
NaN |
NaN |
NaN |
2 |
Tina |
Ali |
36.0 |
f |
NaN |
NaN |
3 |
Jake |
Milner |
24.0 |
m |
2.0 |
62.0 |
4 |
Amy |
Cooze |
73.0 |
f |
3.0 |
70.0 |
df.isnull().sum() / len(df)
first_name 0.2
last_name 0.2
age 0.2
sex 0.2
preTestScore 0.4
postTestScore 0.4
dtype: float64
df_no_missing = df.dropna()
df_no_missing
|
first_name |
last_name |
age |
sex |
preTestScore |
postTestScore |
0 |
Jason |
Miller |
42.0 |
m |
4.0 |
25.0 |
3 |
Jake |
Milner |
24.0 |
m |
2.0 |
62.0 |
4 |
Amy |
Cooze |
73.0 |
f |
3.0 |
70.0 |
df
|
first_name |
last_name |
age |
sex |
preTestScore |
postTestScore |
0 |
Jason |
Miller |
42.0 |
m |
4.0 |
25.0 |
1 |
NaN |
NaN |
NaN |
NaN |
NaN |
NaN |
2 |
Tina |
Ali |
36.0 |
f |
NaN |
NaN |
3 |
Jake |
Milner |
24.0 |
m |
2.0 |
62.0 |
4 |
Amy |
Cooze |
73.0 |
f |
3.0 |
70.0 |
df_cleaned = df.dropna(how='all')
df_cleaned
|
first_name |
last_name |
age |
sex |
preTestScore |
postTestScore |
0 |
Jason |
Miller |
42.0 |
m |
4.0 |
25.0 |
2 |
Tina |
Ali |
36.0 |
f |
NaN |
NaN |
3 |
Jake |
Milner |
24.0 |
m |
2.0 |
62.0 |
4 |
Amy |
Cooze |
73.0 |
f |
3.0 |
70.0 |
df['location'] = np.nan
df
|
first_name |
last_name |
age |
sex |
preTestScore |
postTestScore |
location |
0 |
Jason |
Miller |
42.0 |
m |
4.0 |
25.0 |
NaN |
1 |
NaN |
NaN |
NaN |
NaN |
NaN |
NaN |
NaN |
2 |
Tina |
Ali |
36.0 |
f |
NaN |
NaN |
NaN |
3 |
Jake |
Milner |
24.0 |
m |
2.0 |
62.0 |
NaN |
4 |
Amy |
Cooze |
73.0 |
f |
3.0 |
70.0 |
NaN |
df.dropna(axis=1, how='all')
|
first_name |
last_name |
age |
sex |
preTestScore |
postTestScore |
0 |
Jason |
Miller |
42.0 |
m |
4.0 |
25.0 |
1 |
NaN |
NaN |
NaN |
NaN |
NaN |
NaN |
2 |
Tina |
Ali |
36.0 |
f |
NaN |
NaN |
3 |
Jake |
Milner |
24.0 |
m |
2.0 |
62.0 |
4 |
Amy |
Cooze |
73.0 |
f |
3.0 |
70.0 |
df.dropna(axis=1, thresh = 3)
|
first_name |
last_name |
age |
sex |
preTestScore |
postTestScore |
0 |
Jason |
Miller |
42.0 |
m |
4.0 |
25.0 |
1 |
NaN |
NaN |
NaN |
NaN |
NaN |
NaN |
2 |
Tina |
Ali |
36.0 |
f |
NaN |
NaN |
3 |
Jake |
Milner |
24.0 |
m |
2.0 |
62.0 |
4 |
Amy |
Cooze |
73.0 |
f |
3.0 |
70.0 |
df.dropna(axis=0, thresh=1)
|
first_name |
last_name |
age |
sex |
preTestScore |
postTestScore |
location |
0 |
Jason |
Miller |
42.0 |
m |
4.0 |
25.0 |
NaN |
2 |
Tina |
Ali |
36.0 |
f |
NaN |
NaN |
NaN |
3 |
Jake |
Milner |
24.0 |
m |
2.0 |
62.0 |
NaN |
4 |
Amy |
Cooze |
73.0 |
f |
3.0 |
70.0 |
NaN |
df.dropna(thresh=5)
|
first_name |
last_name |
age |
sex |
preTestScore |
postTestScore |
location |
0 |
Jason |
Miller |
42.0 |
m |
4.0 |
25.0 |
NaN |
3 |
Jake |
Milner |
24.0 |
m |
2.0 |
62.0 |
NaN |
4 |
Amy |
Cooze |
73.0 |
f |
3.0 |
70.0 |
NaN |
데이터 값 채우기
df["preTestScore"].mean()
3.0
df["postTestScore"].median()
62.0
df["postTestScore"].mode()
0 25.0
1 62.0
2 70.0
dtype: float64
Data Fill
df.fillna(0)
|
first_name |
last_name |
age |
sex |
preTestScore |
postTestScore |
location |
0 |
Jason |
Miller |
42.0 |
m |
4.0 |
25.0 |
0.0 |
1 |
0 |
0 |
0.0 |
0 |
0.0 |
0.0 |
0.0 |
2 |
Tina |
Ali |
36.0 |
f |
0.0 |
0.0 |
0.0 |
3 |
Jake |
Milner |
24.0 |
m |
2.0 |
62.0 |
0.0 |
4 |
Amy |
Cooze |
73.0 |
f |
3.0 |
70.0 |
0.0 |
df["preTestScore"].fillna(df["preTestScore"].mean(), inplace=True)
df
|
first_name |
last_name |
age |
sex |
preTestScore |
postTestScore |
location |
0 |
Jason |
Miller |
42.0 |
m |
4.0 |
25.0 |
NaN |
1 |
NaN |
NaN |
NaN |
NaN |
3.0 |
NaN |
NaN |
2 |
Tina |
Ali |
36.0 |
f |
3.0 |
NaN |
NaN |
3 |
Jake |
Milner |
24.0 |
m |
2.0 |
62.0 |
NaN |
4 |
Amy |
Cooze |
73.0 |
f |
3.0 |
70.0 |
NaN |
df.groupby("sex")["postTestScore"].transform("mean")
0 43.5
1 NaN
2 70.0
3 43.5
4 70.0
Name: postTestScore, dtype: float64
df["postTestScore"].fillna(
df.groupby("sex")["postTestScore"].transform("mean"), inplace=True)
df
|
first_name |
last_name |
age |
sex |
preTestScore |
postTestScore |
location |
0 |
Jason |
Miller |
42.0 |
m |
4.0 |
25.0 |
NaN |
1 |
NaN |
NaN |
NaN |
NaN |
3.0 |
NaN |
NaN |
2 |
Tina |
Ali |
36.0 |
f |
3.0 |
70.0 |
NaN |
3 |
Jake |
Milner |
24.0 |
m |
2.0 |
62.0 |
NaN |
4 |
Amy |
Cooze |
73.0 |
f |
3.0 |
70.0 |
NaN |
https://www.boostcourse.org/ai222/lecture/24076