NAN/Python

[Pandas] 기초 활용_Titanic

onddd 2021. 7. 3. 17:56
728x90

NaN Data


머신러닝과 같은 데이터를 이용한 작업을 할 때, 누락 데이터를 처리하는 것은 데이터 품질을 높일 뿐 아니라,

 

성능 향상과도 매우 밀접한 관련이 있다. NaN(Not a Number) 즉, 누락 데이터를 확인하고 처리하는 방법은

 

필수적으로 알고있어야 한다.


 

 

seaborn으로 데이터 불러오기

 

 

seaborn에는 여러 data가 집합해있다. 약어로 sns라고 하며 이를 통해 titanic에 관련된 데이터를 불러올 수 있다.

 

이렇게 불러온 data는 그 양이 많아 한 눈에 담기 어려운데, 이때 사용할 수 있는 메서드가 head( ), tail( ) 함수이다.

 

예시에서 확인 할 수 있듯이 tail( )은 기본 값으로 data의 맨 끝에 존재하는 5개의 data를 불러온다.

 

head( ) 메서드는 이와 반대로 앞에서 5개의 data를 불러오는 함수이다.

 

# data 불러오기
import seaborn as sns

df = sns.load_dataset('titanic')
df.tail()

	survived	pclass	sex	age	sibsp	parch	fare	embarked	class	who	adult_male	deck	embark_town	alive	alone
886	0	2	male	27.0	0	0	13.00	S	Second	man	True	NaN	Southampton	no	True
887	1	1	female	19.0	0	0	30.00	S	First	woman	False	B	Southampton	yes	True
888	0	3	female	NaN	1	2	23.45	S	Third	woman	False	NaN	Southampton	no	False
889	1	1	male	26.0	0	0	30.00	C	First	man	True	C	Cherbourg	yes	True
890	0	3	male	32.0	0	0	7.75	Q	Third	man	True	NaN	Queenstown	no	True

 

 

' data ' . info( )

 

 

이름 그대로 정보를 불러오는 메서드로 사용 시 각 열(column)의 총 개수와 그 유효 데이터(Non-null count)가

 

몇 개 존재하는지 확 인 할 수 있다.

 

# 요약 정보를 통해 누락 데이터 확인

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.6+ KB

 

 

value_counts( )

 

 

info를 통해 각 열마다 존재하는 유효 데이터를 탐색했다면, 어떤 열(column)이 전체 대비 누락 데이터가 많은지도

 

파악할 수 있는데, titanic의 경우 'deck'과 'age' 데이터에 유효 데이터 수가 적은걸 확인할 수 있었다.

 

이때 value_counts( ) 메서드를 이용한다면 보다 정확하게 해당 열의 누락 데이터 수와 유효 데이터를 알아볼 수 있다.

 

# value_count()메소드를 통해 누락률이 많은 열 탐색

nan_df = df['deck'].value_counts(dropna=False)
nan_df

NaN    688
C       59
B       47
D       33
E       32
A       15
F       13
G        4
Name: deck, dtype: int64

 

 

 

isnull( )

 

 

isnull( ), notnull( ) 메서드 역시 누락 데이터를 확인할 수 있는 메서드인데, isnull( )의 경우 전체 데이터에서 

 

누락된 데이터에는 True를 반환하고 유효 데이터에는 False를 반환한다.

 

notnull( ) 데이터는 isnull( )과 반대로 작동된다.

# isnull == data가 null,NaN 일 때 해당 되는 원소를 True로 반환

df.head().isnull()

	survived	pclass	sex	age	sibsp	parch	fare	embarked	class	who	adult_male	deck	embark_town	alive	alone
0	False	False	False	False	False	False	False	False	False	False	False	True	False	False	False
1	False	False	False	False	False	False	False	False	False	False	False	False	False	False	False
2	False	False	False	False	False	False	False	False	False	False	False	True	False	False	False
3	False	False	False	False	False	False	False	False	False	False	False	False	False	False	False
4	False	False	False	False	False	False	False	False	False	False	False	True	False	False	False

 

 

isnull( ). sum(axis = )

 

 

info( ) 메서드와 value_counts( ) 메서드를 조합하지 않고 전체 누락 데이터 개 수를 파악하는 함수이다.

 

axis = 를 통해 행, 열을 조절할 수 있다.

# isnull().sum(axis = ) 를 사용하면 한 번에 누락 데이터의 개 수 파악 가능

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

 

 

dropna( axis = , thresh = )

 

 

NaN data를 구했다면 이제 그 데이터를 제거하는 방법을 알아보자

 

보통 데이터 처리를 할 때 'deck'과 같이 지나치게 누락 데이터가 많을 경우 그 데이터를 제거해야

 

데이터 품질 향상에 도움이 된다.

 

예시의 코드를 읽어보면 dropna(axis=1, thresh = 445)를 통해 제거할 축을 지정하고, 기준을 정해

 

누락 데이터가 절반을 넘을 경우 제거한다고 입력했다.

 

 

# dropna(axis = , thresh = )를 사용 축을 지정한다.
# thresh 옵션을 통해 누락률이 전체 데이터 절반이 넘는 열을 제거

ndf = df.dropna(axis=1, thresh=445)
ndf.columns
ndf

	survived	pclass	sex	age	sibsp	parch	fare	embarked	class	who	adult_male	embark_town	alive	alone
0	0	3	male	22.0	1	0	7.2500	S	Third	man	True	Southampton	no	False
1	1	1	female	38.0	1	0	71.2833	C	First	woman	False	Cherbourg	yes	False
2	1	3	female	26.0	0	0	7.9250	S	Third	woman	False	Southampton	yes	True
3	1	1	female	35.0	1	0	53.1000	S	First	woman	False	Southampton	yes	False
4	0	3	male	35.0	0	0	8.0500	S	Third	man	True	Southampton	no	True
...	...	...	...	...	...	...	...	...	...	...	...	...	...	...
886	0	2	male	27.0	0	0	13.0000	S	Second	man	True	Southampton	no	True
887	1	1	female	19.0	0	0	30.0000	S	First	woman	False	Southampton	yes	True
888	0	3	female	NaN	1	2	23.4500	S	Third	woman	False	Southampton	no	False
889	1	1	male	26.0	0	0	30.0000	C	First	man	True	Cherbourg	yes	True
890	0	3	male	32.0	0	0	7.7500	Q	Third	man	True	Queenstown	no	True

 

 

 

데이터 .dropna(subset=[' 열 선택 '], how='any', axis = 0)

 

 

데이터 품질 향상을 위해 누락 데이터가 많은 데이터를 제거하는 게 좋지만,

 

그렇다고 너무 많은 데이터를 제거하는 것 역시 데이터 품질에 좋은 영향을 끼치진 않는다.

 

두 번째로 누락률이 높았던 'age' 열을 제거하는 게 아닌, 정재하여 데이터 품질을 향상해 보자

 

dropna( ) 메서드는 여러 옵션을 가지고 있는데 그중 how 옵션은 누락 데이터만을 제거하는 게 가능하다.

 

how='any'를 입력하여 누락 데이터를 제거하자.

 

# 누락 데이터가 두 번째로 많은 'age'열을 dropna() 메소드의 how 옵션을 이용하여 
# 누락 데이터를 가진 행만 제거
# how='any'를 사용하면 누락 데이터가 존재하는 모든 행을 제거한다.

ndf2 = ndf.dropna(subset=['age'], how='any',axis = 0)
print(ndf2.isnull().sum(axis=0))
print()
print(ndf2.notnull().sum(axis=0))

survived       0
pclass         0
sex            0
age            0
sibsp          0
parch          0
fare           0
embarked       2
class          0
who            0
adult_male     0
embark_town    2
alive          0
alone          0
dtype: int64

survived       714
pclass         714
sex            714
age            714
sibsp          714
parch          714
fare           714
embarked       712
class          714
who            714
adult_male     714
embark_town    712
alive          714
alone          714
dtype: int64

 

median( )

 

dropna how를 통해 누락 데이터를 제거했다면 비어 있는 데이터 값은 평균값과 같은 대체 데이터로 채워주는 게 좋다.

 

df [ ' 행열 이름 ' ]. median(axis=0) 함수를 사용하면 해당 행/열의 전체 데이터 평균값을 입력한다.

 

 

# 누락 데이터가 445 이상인 데이터 제거
df.dropna(axis=1, thresh=445, inplace=True)

# age열의 누락 데이터를 평균값으로 채우기

age_median = df['age'].median(axis=0)
df['age'].fillna(age_median, inplace = True)
df.isnull().sum(axis= 0)

	survived	pclass	sex	age	sibsp	parch	fare	embarked	class	who	adult_male	embark_town	alive	alone
886	0	2	male	27.0	0	0	13.00	S	Second	man	True	Southampton	no	True
887	1	1	female	19.0	0	0	30.00	S	First	woman	False	Southampton	yes	True
888	0	3	female	28.0	1	2	23.45	S	Third	woman	False	Southampton	no	False
889	1	1	male	26.0	0	0	30.00	C	First	man	True	Cherbourg	yes	True
890	0	3	male	32.0	0	0	7.75	Q	Third	man	True	Queenstown	no	True

 

 

notnull( )

 

유효 데이터에는 True 반환 누락 데이터는 False

# notnull() == 유효한 data 일 경우 True 반환 null, NaN은 False

df.head().notnull()

	survived	pclass	sex	age	sibsp	parch	fare	embarked	class	who	adult_male	deck	embark_town	alive	alone
0	True	True	True	True	True	True	True	True	True	True	True	False	True	True	True
1	True	True	True	True	True	True	True	True	True	True	True	True	True	True	True
2	True	True	True	True	True	True	True	True	True	True	True	False	True	True	True
3	True	True	True	True	True	True	True	True	True	True	True	True	True	True	True
4	True	True	True	True	True	True	True	True	True	True	True	False	True	True	True