Just Fighting
[EDA] 데이터 정제하기 본문
https://kevinprinsloo.medium.com/advanced-eda-e6fea0193dbd
2022.07.17 - [Python] - [EDA] 데이터 구조 살펴보기
데이터 구조를 살펴보았으니 이번에는 데이터의 중복값과 결측치들을 제거해
데이터를 분석하기 좋은 데이터로 만드는 방법을 정리하고자 한다.
중복이 있는 데이터를 찾을 때는 duplicated() 함수를 사용한다.
아래 코드의 의미는 데이터 중에서 'Accident_Index'라는 컬럼을 제외한 나머지 컬럼들 중
중복되는 행을 찾아 그 개수를 나타내고자 함이다.
총 22개의 행이 겹치는 것을 확인했다.
df_X.drop(labels=['Accident_Index'], axis=1).duplicated().sum()
중복되는 데이터를 삭제하고 싶을 때는 drop_duplicates() 함수를 사용한다.
subset은 중복되면 지우고 싶은 컬럼을 써주면 된다.
inplace는 복사본을 만드느냐 마느냐인데, False면 원본 데이터는 변하지 않고 새로운 복사본을 리턴하기 때문에
새로운 변수에 할당을 해주어야하고, True면 원본 데이터가 변경된다.
df_X.drop_duplicates(subset='컬럼명', inplace=True) # inplace는 복사본을 만드느냐 마느냐 True면 만듦
각 행별로 결측치가 얼마나 있느냐를 히트맵을 이용해 표현하는 코드이다.
plt.figure(figsize=(15, 8))
sns.set_style('whitegrid')
g = sns.heatmap(df_X.loc[df_X.isnull().sum(1).sort_values(ascending=True).index].isnull(), cbar=False, cmap='viridis')
g.set_xlabel('Column Number')
g.set_ylabel('Sample Number')
#Text(115.0, 0.5, 'Sample Number')
import missingno as msno
msno.matrix(df_X, labels=True, sort='descending', color=(0.27, 0.52, 1.0));
위의 그래프에서 결측치가 얼마나 있는지 눈으로 확인할 수 있었다.
이제 결측치가 많은 데이터를 삭제해보자.
이전에 shape보다 줄은 것을 확인할 수 있다.
# 20퍼센트 이상이 결측치인 행을 삭제하겠다.
df_X = df_X.dropna(thresh=df_X.shape[1] * 0.80, axis=0).reset_index(drop=True)
df_X.shape
지금까지는 각 행별로 결측치가 얼마나 있는지 확인했다.
이번에는 각 열에 결측치가 얼마나 있는지 확인해보자.
# 각 열마다 결측치의 비율이 얼마나 되는지 그래프로 확인 가능
df_X.isna().mean().sort_values().plot(
kind="bar", figsize=(15, 4),
title="Percentage of missing values per feature",
ylabel="Ratio of missing values per feature");
행과 똑같이 결측치가 많은 열을 제거하자.
axis=0이면 행을 의미하고 1이면 열을 의미한다.
이번에는 열의 개수가 줄어든 것을 확인할 수 있다.
# 컬럼 중에서 결측치가 15퍼센트 이상인 컬럼을 삭제
df_X = df_X.dropna(thresh=df_X.shape[0] * 0.85, axis=1)
df_X.shape
필요없는 데이터들을 제거 했으니 데이터들이 어떻게 형성되어 있는지 봐보자.
# 수치 데이터의 전반적인 분포를 알 수 있는 그래프
df_X.plot(lw=0, marker=".", subplots=True, layout=(-1, 4),
figsize=(15, 30), markersize=1);
# 3개의 서브플롯으로 그림 객체 생성
fig, axes = plt.subplots(ncols=1, nrows=3, figsize=(12, 8))
# 숫자가 아닌 피쳐 필터링
df_non_numerical = df_X.select_dtypes(exclude=["number", "datetime"])
# 반복을 통해 3개의 플롯을 그리는 for문
for col, ax in zip(df_non_numerical.columns, axes.ravel()): # ravel() : 다차원배열을 1차원배열로 만들어줌. 옵션값있음. 복사본 생성안함.
# 발생 횟수를 카운트해 plot으로 그림
df_non_numerical[col].value_counts().plot(logy=True, title=col, lw=0, marker=".", ax=ax)
plt.tight_layout();
마지막으로 가장 많이 일어나는 사고들의 데이터만 보고 싶다면
바로 위에서 생성한 df_non_numerical 중 'Accident_Index' 에서 가장 많이 관측되는 값만 찾아서
데이터를 필터링해주면 된다.
# 가장 많이일어나는 사고 10개만 선택
accident_ids = df_non_numerical["Accident_Index"].value_counts().head(10).index
# accident_ids에 속하지 않는 데이터는 제거
df_X = df_X[~df_X["Accident_Index"].isin(accident_ids)]
df_X.shape
'Python' 카테고리의 다른 글
[Python] Joblib으로 객체 저장하기 (0) | 2022.09.29 |
---|---|
[EDA] 데이터 내용 살펴보기 (0) | 2022.07.17 |
[EDA] 데이터 구조 살펴보기 (0) | 2022.07.17 |
[Flask] API 서버 구축하기 & httpie 사용하기 (0) | 2022.07.01 |
트위터 API 사용하기 (0) | 2022.06.18 |