[Python pandas] 결측값 있는 행 제거, 결측값 있는 행 제거 : dropna(axis=0), dropna(axis=1)
Python 분석과 프로그래밍/Python 데이터 전처리 2016. 12. 10. 23:10지난번 포스팅에서는 Python pandas의 fillna() method를 사용한
에 대해서 알아보았습니다.
이번 포스팅에서는 Python pandas의 dropna() method를 사용해서
- 결측값이 들어있는 행 전체 제거
(delete row with missing values),
- 결측값이 들어있는 열 전체를 제거
(delete column with missing values)
- 특정 행 또는 열 만을 대상으로 결측값이 들어있으면 제거
(delete specific row or column with missing values)
하는 방법을 소개하겠습니다.
관측값이 아주 많고 결측값이 별로 없는 경우에는 결측값이 들어있는 행 전체를 삭제하고 분석을 진행해도 무리가 없고 편리할 수 있습니다.
혹은 특정 변수의 결측값 비율이 매우 높고, 결측값을 채워넣을 만한 마땅한 방법이 없는 경우에는 분석의 신뢰성 확보를 위해서 그 변수(행, 칼럼)을 삭제하고 분석을 진행할 필요도 있습니다.
이때 dropna() method 를 사용하면 됩니다.
먼저, 필요한 모듈을 불러오고, 결측값(None 또는 np.nan)이 들어있는 DataFrame을 만들어보겠습니다.
import numpy as np
import pandas as pd
# seeding the random generator for reproducibility
np.random.seed(1004)
## making a sample DataFrame
df = pd.DataFrame(
np.random.randn(5, 4),
columns=['C1', 'C2', 'C3', 'C4']
)
print(df)
# C1 C2 C3 C4
# 0 0.594403 0.402609 -0.805162 0.115126
# 1 -0.753065 -0.784118 1.461576 1.576076
# 2 -0.171318 -0.914482 0.860139 0.358802
# 3 1.729657 -0.497648 1.761870 0.169013
# 4 -1.085237 -0.010652 1.115798 -1.264972
## adding the missing values (None or np.nan)
df.loc[[0, 1], 'C1'] = None
df.loc[2, 'C2'] = np.nan
print(df)
# C1 C2 C3 C4
# 0 NaN 0.402609 -0.805162 0.115126
# 1 NaN -0.784118 1.461576 1.576076
# 2 -0.171318 NaN 0.860139 0.358802
# 3 1.729657 -0.497648 1.761870 0.169013
# 4 -1.085237 -0.010652 1.115798 -1.264972
이제 dropna() method를 사용해서 결측값이 들어있는 행 전체(axis = 0) 삭제, 혹은 결측값이 들어있는 열 전체(axis=1) 삭제해 보겠습니다.
(1) 결측값이 들어있는 행 전체 삭제하기(delete row with NaN) : df.dropna(axis=0)
## deleting rows with missing values
df_drop_row = df.dropna(axis=0)
print(df_drop_row)
# C1 C2 C3 C4
# 3 1.729657 -0.497648 1.761870 0.169013
# 4 -1.085237 -0.010652 1.115798 -1.264972
(2) 결측값이 들어있는 열 전체 삭제하기 (delete column with NaN) : df.dropna(axis=1)
print(df)
# C1 C2 C3 C4
# 0 NaN 0.402609 -0.805162 0.115126
# 1 NaN -0.784118 1.461576 1.576076
# 2 -0.171318 NaN 0.860139 0.358802
# 3 1.729657 -0.497648 1.761870 0.169013
# 4 -1.085237 -0.010652 1.115798 -1.264972
## deleting columns with missing values
df_drop_column = df.dropna(axis=1)
print(df_drop_column)
# C3 C4
# 0 -0.805162 0.115126
# 1 1.461576 1.576076
# 2 0.860139 0.358802
# 3 1.761870 0.169013
# 4 1.115798 -1.264972
(3) 특정 행 또는 열을 대상으로 결측값이 들어있으면 제거
(delete specific row or column with missing values) : df[ ].dropna()
DataFrame의 행 또는 열을 indexing 한 후에 dropna() method를 적용하면 됩니다. dropna() 와 dropna(axis=0)은 동일합니다 (즉, axis=0 은 생략 가능).
아래에 4가지의 예를 들어보았습니다. 원래의 df DataFrame을 어떻게 indexing 하느냐에 따라 결측값이 들어있는 행과 열이 제거되는지 유심히 살펴보시면 금방 이해가 될거예요.
[df DataFrame의 칼럼 'C1' 에서 결측값이 있는 행 제거하기 ==> return Series]
print(df)
# C1 C2 C3 C4
# 0 NaN 0.402609 -0.805162 0.115126
# 1 NaN -0.784118 1.461576 1.576076
# 2 -0.171318 NaN 0.860139 0.358802
# 3 1.729657 -0.497648 1.761870 0.169013
# 4 -1.085237 -0.010652 1.115798 -1.264972
## deleting specific columns with missing values
df['C1'].dropna()
# 2 -0.171318
# 3 1.729657
# 4 -1.085237
# Name: C1, dtype: float64
[df DataFrame의 칼럼 'C1', 'C2', 'C3' 에서 결측값이 있는 행(axis=0, by default) 제거하기, 열(axis=1) 제거하기 ==> return DataFrame]
print(df[['C1', 'C2', 'C3']])
# C1 C2 C3
# 0 NaN 0.402609 -0.805162
# 1 NaN -0.784118 1.461576
# 2 -0.171318 NaN 0.860139
# 3 1.729657 -0.497648 1.761870
# 4 -1.085237 -0.010652 1.11579
## dropping rows with missing values, the same with dropna(axis=0)
df[['C1', 'C2', 'C3']].dropna()
# C1 C2 C3
# 3 1.729657 -0.497648 1.761870
# 4 -1.085237 -0.010652 1.115798
## dropping columns with missing values
df[['C1', 'C2', 'C3']].dropna(axis=1)
# C3
# 0 -0.805162
# 1 1.461576
# 2 0.860139
# 3 1.761870
# 4 1.115798
[df DataFrame의 행 2, 4, 그리고 칼럼 'C1', 'C2', 'C3'에서 결측값이 있는 행 제거하기 ==> return DataFrame]
df.loc[[2, 4], ['C1', 'C2', 'C3']]
# C1 C2 C3
# 2 -0.171318 NaN 0.860139
# 4 -1.085237 -0.010652 1.115798
## droping rows with missing values
df.loc[[2, 4], ['C1', 'C2', 'C3']].dropna(axis=0)
# C1 C2 C3
# 4 -1.085237 -0.010652 1.115798
마지막으로 첨언하자면, 결측값이 들어있는 행 전체, 혹은 열 전체를 삭제하는 것은 데이터 소실, 혹은 데이터 모집단 왜곡의 위험도 있는 만큼 분석에 영향도를 한번 생각해보고 나서 결정하시면 좋겠습니다.
그리고 만약을 대비해서 원본 데이터 (source data)는 그대로 남겨 놓은 상태에서 행 삭제 혹은 열 삭제 후의 DataFrame은 다른 이름으로 copy 해서 사용하실 것을 권합니다.
다음번 포스팅에서는 결측값 보간(interpolation)에 대해서 알아보겠습니다.
많은 도움 되었기를 바랍니다.