데이터프레임에는 원소 데이터 값이 종종 누락되는 경우가 있다.
데이터를 파일로 입력할 때 빠트리거나 파일 형식을 변환하는 과정에서 데이터가 소실되는 것이 주요 원인이다.
일반적으로 유효한 데이터 값이 존재하지 않는 누락 데이터를 NaN( Not a Number ) 으로 표시한다.
'타이타닉 데이터셋을 사용
import seaborn as sns
df= sns.load_dataset('titanic')
결측된 데이터 확인
df.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 891 entries, 0 to 890
Data columns (total 15 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 survived 891 non-null int64
1 pclass 891 non-null int64
2 sex 891 non-null object
3 age 714 non-null float64
4 sibsp 891 non-null int64
5 parch 891 non-null int64
6 fare 891 non-null float64
7 embarked 889 non-null object
8 class 891 non-null category
9 who 891 non-null object
10 adult_male 891 non-null bool
11 deck 203 non-null category
12 embark_town 889 non-null object
13 alive 891 non-null object
14 alone 891 non-null bool
dtypes: bool(2), category(2), float64(2), int64(4), object(5)
memory usage: 80.7+ KB
완전한 데이터는 891 이고
age, deck, embarked, embark_town 에 결측치가 있다.
.value_counts(dropna = Falase) 메소드를 이용하여 'deck' 열의 결측치 수를 파악
df['deck'].value_counts(dropna = False) # nan 값을 드랍하지 않는다.
<결과>
NaN 688
C 59
B 47
D 33
E 32
A 15
F 13
G 4
Name: deck, dtype: int64
.value_counts(normalize=True) 값의 비중을 구한다.
df['deck'].value_counts(normalize=True) # ascending , sort ..
<결과>
C 0.290640
B 0.231527
D 0.162562
E 0.157635
A 0.073892
F 0.064039
G 0.019704
Name: deck, dtype: float64
가장 큰 값을 갖는 값
.value_counts().idxmax()
df['deck'].value_counts().idxmax()
'C'
df['deck'].value_counts().idxmin()
'G'
누락된 데이터 확인
df.isnull().sum(axis=0)
df.isnull().sum(axis=0)
<결과>
survived 0
pclass 0
sex 0
age 177
sibsp 0
parch 0
fare 0
embarked 2
class 0
who 0
adult_male 0
deck 688
embark_town 2
alive 0
alone 0
dtype: int64
'deck' 열 결측치 데이터 처리
누락 데이터 제거
.dropna
df.dropna(subset=['deck'])
<class 'pandas.core.frame.DataFrame'>
Int64Index: 203 entries, 1 to 889
Data columns (total 15 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 survived 203 non-null int64
1 pclass 203 non-null int64
2 sex 203 non-null object
3 age 184 non-null float64
4 sibsp 203 non-null int64
5 parch 203 non-null int64
6 fare 203 non-null float64
7 embarked 201 non-null object
8 class 203 non-null category
9 who 203 non-null object
10 adult_male 203 non-null bool
11 deck 203 non-null category
12 embark_town 201 non-null object
13 alive 203 non-null object
14 alone 203 non-null bool
dtypes: bool(2), category(2), float64(2), int64(4), object(5)
memory usage: 20.3+ KB
'deck 열에 결측치 행이 제거가 되었다.
다중 컬럼 대상 지정 가능
df.dropna(subset=['embarked','embark_town'])
<class 'pandas.core.frame.DataFrame'>
Int64Index: 889 entries, 0 to 890
Data columns (total 15 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 survived 889 non-null int64
1 pclass 889 non-null int64
2 sex 889 non-null object
3 age 712 non-null float64
4 sibsp 889 non-null int64
5 parch 889 non-null int64
6 fare 889 non-null float64
7 embarked 889 non-null object
8 class 889 non-null category
9 who 889 non-null object
10 adult_male 889 non-null bool
11 deck 201 non-null category
12 embark_town 889 non-null object
13 alive 889 non-null object
14 alone 889 non-null bool
dtypes: bool(2), category(2), float64(2), int64(4), object(5)
memory usage: 87.3+ KB
.dropna(thresh=n, axis=1)
df.dropna(thresh=500, axis=1) # deck 속성의 시리즈가 drop 되었다.
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 891 entries, 0 to 890
Data columns (total 14 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 survived 891 non-null int64
1 pclass 891 non-null int64
2 sex 891 non-null object
3 age 714 non-null float64
4 sibsp 891 non-null int64
5 parch 891 non-null int64
6 fare 891 non-null float64
7 embarked 889 non-null object
8 class 891 non-null category
9 who 891 non-null object
10 adult_male 891 non-null bool
11 embark_town 889 non-null object
12 alive 891 non-null object
13 alone 891 non-null bool
dtypes: bool(2), category(1), float64(2), int64(4), object(5)
memory usage: 79.4+ KB
n (500) 개 이상 결측된 데이터가 있는 열을 제거
결측된 데이터 채우기
누락 데이터 평균값으로 대체하기
mean_age = df['age'].mean()
mean_age
<결과>
29.69911764705882
df2 = df[df['age'].isnull()]
print(len(df2))
df2.head()
<결과>
177개의 NaN 값 확인
177
survived pclass sex age sibsp parch fare embarked class who adult_male deck embark_town alive alone
5 0 3 male NaN 0 0 8.4583 Q Third man True NaN Queenstown no True
17 1 2 male NaN 0 0 13.0000 S Second man True NaN Southampton yes True
19 1 3 female NaN 0 0 7.2250 C Third woman False NaN Cherbourg yes True
누락 데이터를 바꿔서 대체할 값으로는 데이터의 분포와 특성을 잘 나타낼 수 있는 평균값, 최빈값 등을 활용한다.
.fillna(v,inplace=True)
원본 객체 변경하려면 inplace=True 옵션 추가
df['age'].fillna(mean_age,inplace=True)
df2 = df[df['age'].isnull()]
print(len(df2))
df2
<결과>
0
survived pclass sex age sibsp parch fare embarked class who adult_male deck embark_town alive alone
결측치가 없는 것을 확인
df['age'].isnull()
0 False
1 False
2 False
3 False
4 False
...
886 False
887 False
888 False
889 False
890 False
Name: age, Length: 891, dtype: bool
누락된 값을 최빈값으로 치환하기
df3 = df[df['embark_town'].isnull()]
print(df3.index)
df3
<결과>
Int64Index([61, 829], dtype='int64')
survived pclass sex age sibsp parch fare embarked class who adult_male deck embark_town alive alone
61 1 1 female 38.0 0 0 80.0 NaN First woman False B NaN yes True
829 1 1 female 62.0 0 0 80.0 NaN First woman False B NaN yes True
최빈값 찾기
most_freq_town = df['embark_town'].value_counts().idxmax()
most_freq_town
'Southampton'
최빈값 채워넣기
df['embark_town'].fillna(most_freq_town).iloc[825:830]
<결과>
825 Queenstown
826 Southampton
827 Cherbourg
828 Queenstown
829 Southampton
Name: embark_town, dtype: object
829 행에 값이 잘 들어간 것을 볼 수 있다.
1행 이전 값으로 채워넣기
method='ffill'
df['embark_town'].fillna(method='ffill').iloc[825:830]
<결과>
825 Queenstown
826 Southampton
827 Cherbourg
828 Queenstown
829 Queenstown
Name: embark_town, dtype: object
누락 데이터가 NaN으로 표시되지 않은 경우
'?' 이거나 '-' 등으로 되어 있을때 np.nan 을 사용하여 변경하는 것이 좋다.
df_.replace('-', np.nan, inplace=True)
중복값 확인
df.duplicated()
0 False
1 False
2 False
3 False
4 False
...
886 True
887 False
888 False
889 False
890 False
Length: 891, dtype: bool
886행에 중복값이 있는 것을 확인
.drop_duplicates()
중복값 제거
df2 = df.drop_duplicates()
df2.duplicated()
<결과>
0 False
1 False
2 False
3 False
4 False
...
885 False
887 False
888 False
889 False
890 False
Length: 784, dtype: bool
886행이 없어진 것을 확인
댓글