[Python Pandas] 결측값을 그룹 평균값으로 채우기 (Fill missing values by Group means)
Python 분석과 프로그래밍/Python 데이터 전처리 2018. 12. 19. 22:26- 결측값 채우기 (http://rfriend.tistory.com/262) : fillna()
- 결측값이 있는 행 제거 (http://rfriend.tistory.com/263) : dropna()
- GroupBy를 활용한 그룹별 가중평균 구하기 (http://rfriend.tistory.com/397) : groupby()
이번 포스팅에서는 이전 포스팅의 내용들을 결합하여 '결측값을 그룹 별 평균값으로 채우기 (Fill missing values using the group means)' 를 해보겠습니다.
먼저 예제로 사용할 'a'와 'b' 두 개의 그룹을 가지고 있고, 'col_1'과 'col_2'의 두 개의 칼럼을 가지고 있는 간단한 데이터프레임을 만들어보겠습니다.
In [1]: import numpy as np ...: import pandas as pd In [2]: np.random.seed(123) # for reproducibility In [3]: df = pd.DataFrame({'grp': ['a', 'a', 'a', 'a', 'b', 'b', 'b', 'b'], ...: 'col_1': np.random.randn(8), ...: 'col_2': np.random.randn(8)}) ...: ...: df Out[3]: col_1 col_2 grp 0 -1.085631 1.265936 a 1 0.997345 -0.866740 a 2 0.282978 -0.678886 a 3 -1.506295 -0.094709 a 4 -0.578600 1.491390 b 5 1.651437 -0.638902 b 6 -2.426679 -0.443982 b
7 -0.428913 -0.434351 b
|
다음으로 그룹 'a'와 'b'별로 'col_1'과 'col_2' 칼럼에 각각 하나씩 결측값(missing value, NaN)을 집어넣어보겠습니다.
In [4]: df.loc[[1, 6], ['col_1', 'col_2']] = np.nan ...: df Out[4]: col_1 col_2 grp 0 -1.085631 1.265936 a 1 NaN NaN a 2 0.282978 -0.678886 a 3 -1.506295 -0.094709 a 4 -0.578600 1.491390 b 5 1.651437 -0.638902 b 6 NaN NaN b
7 -0.428913 -0.434351 b
|
'a'와 'b' 그룹별 'col_1'과 'col_2' 칼럼의 평균을 계산해보니 아래와 같군요. 이 그룹별 칼럼별 평균 값으로 결측값을 대체하려는 것입니다.
In [5]: df.groupby('grp').mean() ...: Out[5]: col_1 col_2 grp a -0.769649 0.164114
b 0.214641 0.139379
|
자, 이제 준비가 되었으니 GroupBy operator와 lambda 함수, 그리고 apply() 를 사용해서 그룹별 칼럼별 평균을 가지고 결측값을 채워(imputation)보겠습니다.
In [6]: fill_mean_func = lambda g: g.fillna(g.mean()) In [7]: df.groupby('grp').apply(fill_mean_func) Out[7]: col_1 col_2 grp grp a 0 -1.085631 1.265936 a 1 -0.769649 0.164114 a 2 0.282978 -0.678886 a 3 -1.506295 -0.094709 a b 4 -0.578600 1.491390 b 5 1.651437 -0.638902 b 6 0.214641 0.139379 b
7 -0.428913 -0.434351 b
|
만약에 각 "그룹별"로 "특정 값(specific value)"을 가지고 결측값을 대체하고 싶다면 아래의 코드를 참고하세요.
In [8]: fill_values = {'a': 1.0, 'b': 0.5} In [9]: fill_func = lambda d: d.fillna(fill_values[d.name]) In [10]: df.groupby('grp').apply(fill_func) Out[10]: col_1 col_2 grp 0 -1.085631 1.265936 a 1 1.000000 1.000000 a 2 0.282978 -0.678886 a 3 -1.506295 -0.094709 a 4 -0.578600 1.491390 b 5 1.651437 -0.638902 b 6 0.500000 0.500000 b
7 -0.428913 -0.434351 b
|
많은 도움이 되었기를 바랍니다.
이번 포스팅이 도움이 되었다면 아래의 '공감~'를 꾹 눌러주세요. ^^