DataFrameGroupby.filter(func, dropna=True, *args, **Kwargs)
매개변수
func
dropna
*args, **kwargs
import numpy as np
import pandas as pd
# cnt1 값의 범위: 사과: 10대, 귤: 20대, 배: 단단위, 딸기 30이상로 설정
data = dict(fruits=['사과', '사과','사과', '사과','사과','귤','귤','귤','귤','귤','배','배','배','배','배','딸기','딸기','딸기','딸기','딸기']
,cnt1=[10, 12, 13, 11, 12, 21, 22, 27, 24, 26, 7, 7, 8, 3, 2, 30, 35, 37, 41, 28]
,cnt2=[100, 103, 107, 107, 101, 51, 57, 58, 57, 51, 9, 9, 5, 7, 7, 208, 217, 213, 206, 204]
)
df = pd.DataFrame(data)
df
fruits cnt1 cnt2
0 사과 10 100
1 사과 12 103
2 사과 13 107
3 사과 11 107
4 사과 12 101
5 귤 21 51
6 귤 22 57
7 귤 27 58
8 귤 24 57
9 귤 26 51
10 배 7 9
11 배 7 9
12 배 8 5
13 배 3 7
14 배 2 7
15 딸기 30 208
16 딸기 35 217
17 딸기 37 213
18 딸기 41 206
19 딸기 28 204
cnt1의 평균이 20 이상인 과일 데이터를 조회해보자
1. filter를 안쓰고 구하기
# 과일별 cnt1의 평균
result = df.groupby('fruits')['cnt1'].mean()
# boolean indexing을 이용해 result2 지정
# 과일별 cnt1의 평균이 20 이상인 값들
result2 = result[result >= 20]
# result2의 인덱스
Index(['귤', '딸기'], dtype='object', name='fruits')
# 과일 중 result2의 인덱스가 포함된 데이터 조회
df[df['fruits'].isin(list(result2.index))]
fruits cnt1 cnt2
5 귤 21 51
6 귤 22 57
7 귤 27 58
8 귤 24 57
9 귤 26 51
15 딸기 30 208
16 딸기 35 217
17 딸기 37 213
18 딸기 41 206
19 딸기 28 204
2. filter을 사용해보자
2-1. 함수 사용
def mean_20(df):
return df['cnt1'].mean() >= 20
df.groupby('fruits').filter(mean_20)
fruits cnt1 cnt2
5 귤 21 51
6 귤 22 57
7 귤 27 58
8 귤 24 57
9 귤 26 51
15 딸기 30 208
16 딸기 35 217
17 딸기 37 213
18 딸기 41 206
19 딸기 28 204
2-1. lambda 표현식 사용
df.groupby('fruits').filter(lambda df : df['cnt1'].mean() >= 20)
DataFrameGroupBy.transform(func, * args)
SeriesGroupBy.transform(func, *args)
# 사과의 cnt1, 귤의 cnt1, 사과의 cnt2, 귤의 cnt2...평균
result = df.groupby('fruits').transform('mean')
result
cnt1 cnt2
0 11.6 103.6
1 11.6 103.6
2 11.6 103.6
3 11.6 103.6
4 11.6 103.6
5 24.0 54.8
6 24.0 54.8
7 24.0 54.8
8 24.0 54.8
9 24.0 54.8
10 5.4 7.4
11 5.4 7.4
12 5.4 7.4
13 5.4 7.4
14 5.4 7.4
15 34.2 209.6
16 34.2 209.6
17 34.2 209.6
18 34.2 209.6
19 34.2 209.6
과일들의 값을 평균과 비교
# 새로운 컬럼 추가하기
# column을 삽입 - df.insert(삽입할 컬럼 순번, 컬럼이름, 값들)원본을 바꿔버림
# 원하는 위치에 생성가능
df.insert(1, 'cnt1평균', result['cnt1'])
# 컬럼의 끝에 생성
df['cnt2평균'] = result['cnt2']
df
fruits cnt1평균 cnt1 cnt2 cnt2평균
0 사과 11.6 10 100 103.6
1 사과 11.6 12 103 103.6
2 사과 11.6 13 107 103.6
3 사과 11.6 11 107 103.6
4 사과 11.6 12 101 103.6
5 귤 24.0 21 51 54.8
6 귤 24.0 22 57 54.8
7 귤 24.0 27 58 54.8
8 귤 24.0 24 57 54.8
9 귤 24.0 26 51 54.8
10 배 5.4 7 9 7.4
11 배 5.4 7 9 7.4
12 배 5.4 8 5 7.4
13 배 5.4 3 7 7.4
14 배 5.4 2 7 7.4
15 딸기 34.2 30 208 209.6
16 딸기 34.2 35 217 209.6
17 딸기 34.2 37 213 209.6
18 딸기 34.2 41 206 209.6
19 딸기 34.2 28 204 209.6
# cnt2의 0,1,5,6,10,11,15,16에 결측치 생성
df2 = pd.DataFrame(data)
df2.loc[[0,1,5,6,10,11,15,16], 'cnt2'] =np.nan
df2
fruits cnt1 cnt2
0 사과 10 NaN
1 사과 12 NaN
2 사과 13 107.0
3 사과 11 107.0
4 사과 12 101.0
5 귤 21 NaN
6 귤 22 NaN
7 귤 27 58.0
8 귤 24 57.0
9 귤 26 51.0
10 배 7 NaN
11 배 7 NaN
12 배 8 5.0
13 배 3 7.0
14 배 2 7.0
15 딸기 30 NaN
16 딸기 35 NaN
17 딸기 37 213.0
18 딸기 41 206.0
19 딸기 28 204.0
# axis=1을 하면 cnt2 칼럼이 사라짐
df2.dropna(axis=1)
fruits cnt1
0 사과 10
1 사과 12
2 사과 13
3 사과 11
4 사과 12
5 귤 21
6 귤 22
7 귤 27
8 귤 24
9 귤 26
10 배 7
11 배 7
12 배 8
13 배 3
14 배 2
15 딸기 30
16 딸기 35
17 딸기 37
18 딸기 41
19 딸기 28
# axis=0 하면 결측치에 해당되는 행이 사라짐
df2.dropna(axis=0)
fruits cnt1 cnt2
2 사과 13 107.0
3 사과 11 107.0
4 사과 12 101.0
7 귤 27 58.0
8 귤 24 57.0
9 귤 26 51.0
12 배 8 5.0
13 배 3 7.0
14 배 2 7.0
17 딸기 37 213.0
18 딸기 41 206.0
19 딸기 28 204.0
dataframe에서 결측치를 처리할 때 제거 하는 것은 좋은 방법이 아니다.
결측치를 평균 값으로 대체해보자
# cnt2의 평균을 구한다.
cnt2_mean = df2['cnt2'].mean()
cnt2_mean
# 구한 평균으로 cnt2의 결측치를 체운다.
df2['cnt2'] = df2['cnt2'].fillna(round(cnt2_mean))
df2
fruits cnt1 cnt2
0 사과 10 94.0
1 사과 12 94.0
2 사과 13 107.0
3 사과 11 107.0
4 사과 12 101.0
5 귤 21 94.0
6 귤 22 94.0
7 귤 27 58.0
8 귤 24 57.0
9 귤 26 51.0
10 배 7 94.0
11 배 7 94.0
12 배 8 5.0
13 배 3 7.0
14 배 2 7.0
15 딸기 30 94.0
16 딸기 35 94.0
17 딸기 37 213.0
18 딸기 41 206.0
19 딸기 28 204.0
비슷한 값으로 바꾸니 괜찮아 보이지만 그룹별로 값의 편차가 있는 곳이 있다.(배 같은 경우 평균이 94와 7이 보인다.)
전체 평균으로 구했기에 이러한 문제가 생긴다.
transform을 사용해 그룹별로 평균을 구해 결측치에 넣어보자.
# cnt2를 그룹별로 평균값을 구함.
df2['cnt2'] = df2['cnt2'].fillna(round(df2.groupby('fruits')['cnt2'].transform('mean')))
df2
fruits cnt1 cnt2
0 사과 10 105.0
1 사과 12 105.0
2 사과 13 107.0
3 사과 11 107.0
4 사과 12 101.0
5 귤 21 55.0
6 귤 22 55.0
7 귤 27 58.0
8 귤 24 57.0
9 귤 26 51.0
10 배 7 6.0
11 배 7 6.0
12 배 8 5.0
13 배 3 7.0
14 배 2 7.0
15 딸기 30 208.0
16 딸기 35 208.0
17 딸기 37 213.0
18 딸기 41 206.0
19 딸기 28 204.0