판다스 groupby 객체의 결측치 채우기

이번 포스팅에서는 판다스 groupby 객체에 결측치가 있을 경우, 간단한 함수와 apply 메서드의 조합으로 이를 채우는 방법을 살펴보겠습니다.

각 그룹별 평균처럼 데이터로부터 도출되는 값을 채우는 방법도 있고, 아니면 이미 지정한 스칼라 값을 일괄적으로 결측치에 채우는 방법도 있습니다.

먼저 결측치를 채우는 기본적인 방법부터 살펴보겠습니다.
예를 들어 아래와 같은 Series가 있다고 가정하겠습니다.
0번 인덱스부터 2칸씩 건너뛰며 결측치를 넣어줍니다.

s = pd.Series(np.random.standard_normal(6))
s[::2] = np.nan

s

이제 이 결측치들을 s의 평균값으로 채워넣어 보겠습니다. 이럴 때는 fillna 메서드를 쓰면 됩니다.

s.fillna(s.mean())

s.mean(), 즉 s의 평균값으로 결측치가 채워졌습니다.
그런데 만약 groupby 객체에서 그룹별로 결측치에 채워넣고 싶은 값이 다르다면 어떻게 해야 할까요?

1. 데이터에서 도출한 특정한 값으로 결측치 채우기

예를 들어보겠습니다.
아래는 미국 동부와 서부의 데이터입니다.

states = [
    "Ohio",
    "New York",
    "Vermont",
    "Florida",
    "Oregon",
    "Nevada",
    "California",
    "Idaho",
]
group_key = ["East", "East", "East", "East", "West", "West", "West", "West"]
data = pd.Series(np.random.standard_normal(8), index=states)
data

다음으로 데이터의 몇몇 값들을 결측치로 만들어 보겠습니다.

data[["Vermont", "Nevada", "Idaho"]] = np.nan
data

버몬트, 네바다, 아이다호의 값이 결측치로 바뀌었습니다.
이제 그룹별로 통계치를 간단히 살펴보겠습니다.

data.groupby(group_key).size()
data.groupby(group_key).count()
data.groupby(group_key).mean()

결측치는 집계에서 제외되므로 size는 4지만 count는 그보다 줄어듦에 유의하셔야 합니다. 이제 각 그룹의 결측치를 해당 그룹의 평균값으로 채워 보겠습니다. 앞선 포스팅링크에서 살펴본 groupby 객체에 apply를 적용하는 방법입니다.

def fill_mean(group):
    return group.fillna(group.mean())


data.groupby(group_key).apply(fill_mean)

East에 속한 버몬트, West에 속한 네바다와 아이다호에 각각 위에서 구한 평균값이 채워진 것을 확인할 수 있습니다.

2. 그룹 속성을 활용해 미리 정의된 값으로 결측치 채우기

두 번째 방법은 그룹의 속성을 활용해, 미리 정의된 값으로 결측치를 채우는 방법입니다. East, West라는 그룹은 내부적으로 name이라는 속성을 가지는데, 이를 활용하는 것입니다.

fill_values = {"East": 0.5, "West": -1}


def fill_func(group):
    return group.fillna(fill_values[group.name])


data.groupby(group_key).apply(fill_func)

group.name이라는 속성을 활용해 East의 결측치에는 0.5, West의 결측치에는 -1을 할당하는 함수를 만들었습니다. 이 함수를 groupby 객체에 적용하면 그룹별로 원하는 값을 결측치에 채워넣을 수 있게 됩니다.


공식 문서 : 링크 pandas.core.groupby.DataFrameGroupBy.fillna

Comments

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다