Py) 전처리 - 결측치 처리-03

Py) 전처리 - 결측치 처리-03

Pandas 객체에 결측치를 처리하는 다양한 패턴을 알아본다. 여기서는 Pandas의 표준 결측표기가 아닌 결측치가 데이터프레임 객체의 다중 변수에 흩어져 있을 때 해당 결측치가 있는 행을 삭제하는 방법을 알아본다.


본 게시물을 온전히 이해하기 위해서는 결측치 처리 기초 게시물 “Py) 기초 - Pandas(결측치)”를 먼저 충분히 숙지하는 것을 추천한다.

개요

Pandas 객체의 원소에 결측치가 있는 행을 삭제하는 방법을 알아본다. 일반적으로 결측치는 pd.NA, np.nan, None 등으로 표기되지만, 데이터의 특징으로 인하여 빈칸, -1, “-“ 등 다양한 방식으로 표기되는 경우도 있다. 이 경우에는 결측치를 처리하기 위한 Pandas 라이브러리 객체의 메서드인 .isna(), .dropna() 같은 것을 쓸 수 없기에 일반적인 Pandas 객체 핸들링 방법으로 결측치를 처리해야 한다.

실습

다음과 같이 라이브러리와 데이터를 준비한다. “df” 데이터프레임 각 변수의 원소 중 -1 을 결측으로 간주하고 처리하는 방법에 대해 알아보고자 한다.

1
2
3
4
5
6
7
8
import pandas as pd

df = pd.DataFrame(dict(col1 = [1, -1, 3, 4, -1, 6, 7, 8],
col2 = [2, 3, 0, 50, 6, 7, 12, 9],
col3 = [3, 4, 5, -1, 7, 8, 9, -1],
col4 = [4, 5, 6, 7, -1, 9, 10, -1],
col5 = [5, -1, 7, 8, 9, -1, 11, 12]))
df
col1 col2 col3 col4 col5
0 1 2 3 4 5
1 -1 3 4 5 -1
2 3 0 5 6 7
3 4 50 -1 7 8
4 -1 6 7 -1 9
5 6 7 8 9 -1
6 7 12 9 10 11
7 8 9 -1 -1 12

개별 변수 처리

데이터프레임 객체의 각 변수별로 처리하는 방법을 알아본다. 기본적인 데이터프레임 핸들링 코드이나 변수의 개수만큼 코드를 작성해야 하기에 번거롭다는 단점이 있다.

1
2
3
4
5
6
df1 = df.loc[df["col1"] != -1, ]
df1 = df1.loc[df["col2"] != -1, ]
df1 = df1.loc[df["col3"] != -1, ]
df1 = df1.loc[df["col4"] != -1, ]
df1 = df1.loc[df["col5"] != -1, ]
df1
col1 col2 col3 col4 col5
0 1 2 3 4 5
2 3 0 5 6 7
6 7 12 9 10 11

반복문 활용

첫 번째 변수부터 마지막 변수까지의 처리를 반복문을 활용하고자 한다. 이 때 첫 번째 변수는 반복문 밖에서 만드는 방법을 사용할 수 있다.

1
2
3
4
5
df2 = df.loc[df.iloc[:, 0] != -1, ]
for n_col in range(1, df.shape[1]):
df2 = df2.loc[df2.iloc[:, n_col] != -1, ]

df2
col1 col2 col3 col4 col5
0 1 2 3 4 5
2 3 0 5 6 7
6 7 12 9 10 11

전체 코드를 반복문 안에 넣으려면 다음과 같이 첫 번째 변수 처리를 if문으로 예외 처리 하는 방법을 사용할 수 있다.

1
2
3
4
5
6
7
for n_col in range(df.shape[1]):
if n_col == 0:
df2 = df.loc[df.iloc[:, 0] != -1, ]
else:
df2 = df2.loc[df2.iloc[:, n_col] != -1, ]

df2
col1 col2 col3 col4 col5
0 1 2 3 4 5
2 3 0 5 6 7
6 7 12 9 10 11

결측 치환 활용

결측치가 있는 행을 제거하려고 할 때 기존에 결측치가 존재하지 않거나 결측치가 있더라도 해당 결측치가 있는 행을 제거해도 무방할 때 다음과 같이 결측으로 간주하는 원소를 결측으로 치환한 후 .dropna() 메서드를 사용하면 깔끔하게 처리할 수 있다.

1
2
df3 = df.replace(-1, pd.NA).dropna()
df3
col1 col2 col3 col4 col5
0 1 2 3 4 5
2 3 0 5 6 7
6 7 12 9 10 11
Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×