본문 바로가기
빅데이터분석

[파이썬] 파이썬 입문 데이터분석 프로젝트 만들기 - (12) groupby 그룹별 집계하기

by 모닥불🔥 2024. 5. 19.

링고선생님의 파이썬 데이터분석 프로젝트 강의!

강의자료로는 3-7 내용이다. 강의는 홈페이지에서 구매할 수 있음..!(사진 누르면 링크 이동)


🔥 강의 목차

오리엔테이션
파이썬 기초 문법
데이터 전처리
데이터 시각화
마케팅 데이터 분석 및 지표 정의하기

🔥 그룹화(df.groupby)

데이터를 집계할 때, 항상 전체 데이터만 집계할 순 없다. '성적' 데이터를 예로 들어 보자. 학교 전체 성적 평균, 표준편차 등을 구하는 것도 물론 의미가 있다. 하지만 반별 평균을 구하거나, 과목별 평균을 구해야 하는 경우가 더 많을 것이다. 즉, 집계를 위해 기준에 따라 그룹화 하는 것이 매우 중요하다.

 

groupby() 코드의 기본 구조는 아래와 같다.

df.gropuby( by = 'col_group' )['col_agg'].agg_func().reset_index()
# 두개 이상의 column 으로 그룹화 하는 경우
## by = 'col_group' -> by =  ['col_group1','col_group2']
# 두개 이상의 column 으로 집계하는 경우 'col_agg' ->  ['col_agg1','col_agg2']
# reset_index() index 로 설정된 'group'을 column으로 만들어줌

 

강의에서는 데이터를 특정 기준에 따라 그룹화(grouping)하고, 집계(aggregation)하는 과정을 분할, 적용, 결합의 3단계로 설명하고 있다.

 

1. Splitting(분할)

분할이란, 데이터를 일정한 기준에 따라 여러 그룹으로 나누는 것이다.

 

일단, 아래 코드로 샘플 데이터를 생성하자. A, B, C 중 어떤 그룹에 속하는지 적어둔 6개의 행이 있다.

import pandas as pd
df = pd.DataFrame({
    'group': ['A', 'A', 'B', 'B', 'C', 'C'],
    'value': [10, 10, 30, 40, 60, 60]
})

 

여기에서 그룹 A에 해당하는 데이터만 뽑으려면 어떻게 해야 할까? 조건문을 사용하면 된다.

df.group으로 컬럼을 선택하든, df['group']으로 컬럼을 선택하든 완전히 동일한 결과가 나온다.

B나 C를 뽑고 싶다면 조건문을 그렇게 쓰면 된다.

# df[조건문]

df[df.group == 'A']
# 또는 df[df['group'] == 'A']

 

2. Applying(적용)

그룹을 쪼개면 집계함수를 사용할 때 그룹별로, 독립적으로 함수를 적용한다.

sum, mean, max, min과 같은 집계함수는 숫자 데이터 계산에 사용하고, count, nunique 같은 함수는 모든 데이터유형(문자, 숫자 등)에 사용할 수 있다.

 

그룹별 값의 합계를 구하려면 어떻게 해야 할까?

df[df.group == 'A']['value'].sum()

 

앞에서 썼던, group이 A에 해당하는 데이터들의 값(value)을 합하라(.sum())는 코드이다. A 그룹에 속하는 데이터는 총 2개, 값은 각각 10, 10이었으므로 합계는 20이 출력된다. 조건에 따라 합계를 다 구할 수 있다.

print('A:', df[df.group == 'A']['value'].sum())
print('B:', df[df.group == 'B']['value'].sum())
print('C:', df[df.group == 'C']['value'].sum())

3. Combining(결합)

그런데 우리가 원하는 건 일일이 조건문을 써서, 그 합계를 따로따로 출력하는 게 아니다. 표 형태로 A의 합계는 20, B의 합계는 70, C의 합계는 120이라고 나타내 주어야 이후 집계된 표를 이용하여 또 다른 계산을 할 수 있기 때문에, 데이터프레임 형태로 결과를 보길 원한다.

 

groupby를 이용하면 앞서 계산한 결과들을 데이터프레임 형태로 나타낼 수 있다.

기본 형태는 df.groupby( by = '그룹화 할 기준 컬럼')['집계를 할 컬럼'].agg_function().reset_index() 이다.

 

- agg_function() 부분에는 sum(), max() 같은 집계 함수를 사용하면 된다.

- eset_index 를 해주는 이유는 index를 다시 설정하지 않으면 group이 index가 되어 버리기 때문이다.

df.groupby( by = 'group')['value'].sum().reset_index()

 

3-1. 집계함수

집계함수는 sum, mean, min, max 같은 함수로, '숫자형 데이터'에서 사용하며 문자형 데이터에 사용할 경우 오류가 발생한다. 단순히 개수를 세는 count()나 유일값의 수를 세는 nunique()는 문자형 데이터에도 사용 가능하다.

아래 집계 함수 적용 결과를 보고, 나중에 필요할 때 필요한 함수를 쓰면 될 것 같다.

 

count()와 nunique() 함수에 대해 조금 더 알아보자. 그룹별로 value2의 개수를 세면 어떤 결과가 나올지 예상해 보자.

A의 값은 None과 d, B의 값은 d, d, C의 값은 None, None이다. 'None'은 데이터가 존재하지 않는다는 의미이다.

df2.groupby(by = 'group')['value2'].count().reset_index()
# none, na, nan, null은 값이 없다는 의미. count를 하지 않는다.

 

count()로 그룹별 개수를 세어 보면, None 값을 제외한 d만 카운트가 된 것을 볼 수 있다. 이처럼 count는 null 값을 세지 않는다는 것에 유의!

 

그렇다면, nunique()는 어떤 역할을 할까?

df2.groupby(by = 'group')['value2'].nunique().reset_index()
# 중복값이 있으면(그룹 b의 d, d) 한 번만 센다.

 

nunique()결과, d가 두 개 였던 B 그룹은 1이라는 결과가 나왔다. count()는 중복값도 관계 없이 세지만 nunique()는 유일값을 세기 때문에 중복값은 제외된다. SQL에서 distinct와 동일한 기능이라고 보면 될 듯!

 

데이터 분석을 할 때, nunique()는 어떤 범주가 있는지 알아볼 때 주로 사용된다. 예를 들어, 붓꽃 데이터에서 species를 nunique() 한다면 3이라는 결과가 나와서 3종류의 붓꽃 종이 있음을 바로 알 수 있다든가... 이건 또 나중에 설명할 기회가 있지 않을까 싶음

 

3-2. groupby.agg()

groupby.agg()를 이용하면 여러 집계 연산을 한 번에 수행할 수도 있다. 기본 형태는 아래와 같다. 똑같이 groupby(by = '기준이 되는 그룹')을 쓴 다음 .agg() 안에 결과를 나타낼 새로운 컬럼명과, 대상 컬럼, 집계 함수를 써주면 된다.

df.groupby(by = 'group').agg(
    col_name1 = ('col1','agg_func')
    , col_name2 = ('col2','agg_func')
    ).reset_index()
# agg_func -> sum, mean, max, min, ...

 

샘플 데이터2로 value의 합계와 value2의 nunique값을 계산해보자.

# 샘플 데이터2

import pandas as pd
df2 = pd.DataFrame({
    'group': ['A', 'A', 'B', 'B', 'C', 'C'],
    'value': [10, 10, 30, 40, 60, 60],
    'value2': [None, 'd', 'd', 'd', None, None]
})
df2
df2.groupby(by='group').agg(
    val2_nunique = ('value2', 'nunique') # 새컬럼명 = ('집계기준 컬럼', '집계함수')
    , val1_sum = ('value', 'sum')
).reset_index()

 

그룹바이는 진짜 진짜 많이 쓰이고, SQL에서도 많이 쓰이고 중요한 개념이라 계속 연습해서 완벽하게 손에 익도록 해야 할 것 같다. 요즘 좀 게을러진 것 같은데 다시 힘내야지... 파이팅...!!🔥🔥

 

 

* 본 게시글은 '메타코드'의 동의를 받아 작성된 글로, 강의 내용에 대한 모든 저작권은 Ringo 선생님에게 있습니다. 개인용도의 학습 외에 무단사용은 엄격히 금지됩니다. 위반 시 법적 조취가 취해질 수 있습니다.