결측치에 그룹별 최빈값 넣기¶
In [1]:
import numpy as np
import pandas as pd
In [73]:
# 데이터프레임 생성
df1 = pd.DataFrame({'col1' : list('a' * 4 + 'b' * 4),
'col2' : [np.nan, 1, 1, 2, np.nan, 3, 2, 1]})
df1
Out[73]:
col1 | col2 | |
---|---|---|
0 | a | NaN |
1 | a | 1.0 |
2 | a | 1.0 |
3 | a | 2.0 |
4 | b | NaN |
5 | b | 3.0 |
6 | b | 2.0 |
7 | b | 1.0 |
In [70]:
# a 그룹에서는 최빈값이 1 하나만 나오지만, b 그룹에서는 최빈값이 여럿이라 1, 2, 3 모두 출력
df1.groupby('col1')['col2'].apply(pd.Series.mode)
Out[70]:
col1
a 0 1.0
b 0 1.0
1 2.0
2 3.0
Name: col2, dtype: float64
In [75]:
# transform 안에 lambda로 정의한 최빈값을 넣어준다.
df1['col2'] = df1['col2'].fillna(df1.groupby('col1')['col2'].transform(lambda x : pd.Series.mode(x)[0]))
df1
Out[75]:
col1 | col2 | |
---|---|---|
0 | a | 1.0 |
1 | a | 1.0 |
2 | a | 1.0 |
3 | a | 2.0 |
4 | b | 1.0 |
5 | b | 3.0 |
6 | b | 2.0 |
7 | b | 1.0 |
In [81]:
# lambda로 자기 자신을 인자로 갖는 mode 함수를 넣어주지 않으면 제대로 적용되지 않는다.
# 아래 df2는 df1과 같은 형태의 데이터프레임이고, transform(pd.Series.mode)만 했을 경우엔 제대로 결측치가 채워지지 않았음을 확인할 수 있다.
df2 = pd.DataFrame({'col1' : list('a' * 4 + 'b' * 4),
'col2' : [np.nan, 1, 1, 2, np.nan, 3, 2, 1]})
df2['col2'] = df2['col2'].fillna(df1.groupby('col1')['col2'].transform(pd.Series.mode))
df2
Out[81]:
col1 | col2 | |
---|---|---|
0 | a | 1.0 |
1 | a | 1.0 |
2 | a | 1.0 |
3 | a | 2.0 |
4 | b | NaN |
5 | b | 3.0 |
6 | b | 2.0 |
7 | b | 1.0 |
'파이썬 팁' 카테고리의 다른 글
list.sort()와 sorted()의 차이, key 인자 활용 (0) | 2022.12.04 |
---|---|
클래스, 메소드 정보 조회하기 (0) | 2022.12.01 |
zip 함수의 활용 (0) | 2022.11.18 |
조건에 맞는 데이터에 값 대입 (0) | 2022.11.11 |
transform 메소드로 결측치에 그룹별 평균값 대입하기 (0) | 2022.11.09 |
댓글