데이터 분석/자료구조(Data structure)

파이썬 - Pandas 기초 정리(DataFrame - 2)

Jerry Jun 2020. 12. 23. 09:18
728x90

이전 게시물에 이어서 학습을 진행한다.

데이터를 분석하여 예측을 하기 위해서는 예측하는 데이터와 어떤 컬럼이 관계가 깊은지 알아야 한다.

이런 경우에 알아보는 것 중 하나가 "상관계수" 이다. 상관계수는 -1 ~ 1 사이의 숫자이다.

예를 들어 A 컬럼과 B 컬럼의 상관계수를 알아봤을 때 1에 가깝다면 A가 증가할 때 B 가 증가하는 형태를 이룬다고 볼 수 있고, -1 에 가깝다면 A가 증가할 때 B는 감소하는 추세를 보인다고 볼 수 있다. 만약 0에 가깝다면 A 와 B는 별로 관계가 없다는 것을 깨달을 수 있다.

1. 상관계수 알아보기

import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
%matplotlib inline

상관계수를 알아보기 쉽게 시각화 하기 위한 모듈을 import 한다.

df.corr()

상관계수

corr( ) 함수를 이용하여 간단하게 상관계수를 알아볼 수 있다. 하지만 한 눈에 보기에 쉽지 않기 때문에 seaborn 라이브러리를 사용한다. 위의 경우를 보면 숫자형 column 만 계산되어 표현한 것을 알 수 있다.

 

sns.heatmap(df.corr())

히트맵

이렇게 시각화를 진행하면 한 눈에 어떤 컬럼이 영향을 미치는지 알 수 있다.

 


2. 결측치 해결하기

데이터를 분석하려고 보면 곳곳에 결측치(NaN)가 숨어있는 경우가 있다. 이러한 경우를 그대로 둔다면 후에 오차가 더 발생할 수 있고, 계산에 오류가 날 수 있다. 그래서 결측치를 삭제 혹은 대체 등을 해야한다. 일단 결측치가 있는지 없는지 체크해보자.

 

(1) 결측치 확인방법 - info( )

df.info()
----------------------------
<class 'pandas.core.frame.DataFrame'>
Int64Index: 891 entries, 1 to 891
Data columns (total 11 columns):
 #   Column    Non-Null Count  Dtype  
---  ------    --------------  -----  
 0   Survived  891 non-null    int64  
 1   Pclass    891 non-null    int64  
 2   Name      891 non-null    object 
 3   Sex       891 non-null    object 
 4   Age       714 non-null    float64
 5   SibSp     891 non-null    int64  
 6   Parch     891 non-null    int64  
 7   Ticket    891 non-null    object 
 8   Fare      891 non-null    float64
 9   Cabin     204 non-null    object 
 10  Embarked  889 non-null    object 
dtypes: float64(2), int64(4), object(5)
memory usage: 83.5+ KB

info( ) 함수를 통해 데이터프레임이 결측치가 있는지 확인할 수 있다. 위의 경우를 봐서는 'Age' 와 'Cabin', 'Embarked' 에서 결측치가 있는 것을 확인할 수 있다.

 

 

(2) 결측치 확인방법 - isna( )

df.isna()

isna 코드실행

isna( ) 의 경우 NaN 값이 있을 때 True 를 반환하게 되는데 데이터가 많을 때에는 한 눈에 알아보기 쉽지 않아서 잘 쓰지 않는다.

 

 

(3) 결측치 확인방법 - missingno

import missingno as msno
msno.bar(df)

missingno 시각화

한 눈에 보기 쉬운 결측 시각화에 자주 쓰이는 missingno 이다. 이해하기 쉽게 bar 로 이미지를 구성해보았다.

이제 결측치를 해결해보자.


2-1 결측치 해결 - 삭제

df.dropna()

결측치 삭제

dropna( ) 를 간단하게 사용한다면 row 를 기준으로 결측치가 있는 행은 모두 삭제된다. 그림에서 보면 결측치가 있었던 값들이 사라진 모습을 볼 수 있다. 여기에서 중요한 것은 결측치(NaN)의 기준을 설정할 수 있다. 예를 들어 'Cabin' 에 결측치가 있어도 'Age' 에서 결측치가 없다면 삭제되지 않도록 만들 수 있다. dropna(subset=['Age']) 를 활용하면 가능하다.

 

 

2-2 결측치 해결 - 대체

만약 데이터가 충분히 많지 않다면 데이터를 삭제하는 것이 손해라고 생각하는 경우가 있다. 그럴 때 결측치를 적당한 데이터로 대체할 수 있다. 전체 데이터의 평균으로 대체할 수도 있고, 가까이 있는 데이터를 가져올 수도 있다.

df['Age'].fillna(df['Age'].mean())

fillna( ) 함수를 이용해 결측값의 위치에 데이터를 넣을 수 있다. 이 경우 전체 나이의 평균을 넣은 것을 볼 수 있다.

 

지금까지의 함수를 실행시켰을 때 데이터프레임에 자동으로 저장되지 않는 점을 유의해야 한다. 자동으로 저장시키기 위해서는 항상 inplace 를 True 로 주어야 한다.

 

df['Age'].fillna(method = 'ffill')


df['Age'].fillna(method = 'bfill')

다음은 결측치 위치의 앞 데이터를 복사해서 대체하는 ffill 과 뒤 데이터를 복사하는 bfill 의 코드이다. 평균이 아니더라도 가까운 데이터를 가져와 대체하는 경우도 가능하다.

 


3. 범주형 데이터 변환하기

범주형 데이터로 되어있을 때는 계산을 하기 힘들다. 그럴 때 숫자형으로 바꾸면 계산이 가능해지는데 이 때 사용하는 것이 One-hot encoding 이다.

 

"One-hot encoding" 이란 해당 범주만 1, 나머지는 0으로 채우는 기법을 말한다. 이 경우를 구현할 때 쓰는 함수가 get_dummies( ) 이다. 하지만 우리는 대부분 원하는 column 만 인코딩하는 경우가 많기 때문에 이를 구현해보자.

pd.get_dummies(df, columns = ['Pclass', 'Sex'])

범주형인 'Pclass' 와 'Sex' 에 대해서 One-hot encoding 을 실행한 결과이다. 사진과 같이 [Pclass_1, Pclass_2, Pclass_3], [Sex_female, Sex_male] 로 나누어진 모습을 볼 수 있다. 여기에서 하나의 팁은 "drop_first" 를 이용하는 것이다. Pclass 도 예시가 될 수 있겠지만 성별의 경우 남자 혹은 여자이기 때문에 [Sex_female, Sex_male] 로 두 개의 컬럼을 잡아먹기 보다는 하나의 컬럼으로 통일해서 1이면 남자 0이면 여자로 구분할 수 있을 것이다.

 

pd.get_dummies(df, columns = ['Sex'], drop_first = True)

이렇게 하나의 컬럼으로 성별을 나눌 수 있다는 것을 알 수 있었다.

 

 

300x250