Pandas/DataFrame/Groupby메소드/일괄처리 메소드 복습

김홍찬·2023년 1월 22일
0

학습내용

  • groupby 메소드
  • 일괄처리 메소드

Groupby 메소드

1. filter()

DataFrameGroupby.filter(func, dropna=True, *args, **Kwargs)

  • 특정 조건을 만족하는 그룹의 데이터들을 조회할 때 사용한다.
  1. 함수에 그룹별 dataframe을 argument로 전달
  2. 받은 dataframe을 이용해 집계한 값의 조건을 비교해서 bool타입으로 반환
  3. 반환값이 True인 그룹들의 모든 행들로 구성된 dataframe을 반환함

매개변수

  • func

    • filtering 조건을 구현함 함수 객체
    • 그룹으로 묶인 dataframe을 받는다.
    • bool type 값을 반환한다.
  • dropna

    • True: filter을 통과하지 못한 그룹의 dataframe의 값들을 drop시킨다.(기본값)
    • Fales: NA(결측치) 처리해서 반환한다.
  • *args, **kwargs

    • filter 함수의 두번째부터 선언된 매개변수에 전달할 argment 값들을 가변인자로 전달한다.
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)

2. transform()

DataFrameGroupBy.transform(func, * args)
SeriesGroupBy.transform(func, *args)

  • transform() 함수를 groupby()와 사용하면 컬럼의 각 원소들을 자신이 속한 그룹의 통계량으로 변화된 데이터셋을 생성할 수 있다.
  • 컬럼의 값과 통계값을 비교해서 보거나 결측치 처리등에 사용한다.
# 사과의 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
  1. 결측치를 없애서 처리
# 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에서 결측치를 처리할 때 제거 하는 것은 좋은 방법이 아니다.

  1. 결측치에 새로운 값 넣기(fransform 활용)
결측치를 평균 값으로 대체해보자

# 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
profile
바쁘다 바빠

0개의 댓글