본문으로 건너뛰기
김신건의 로그

[Pandas] groupby

· 수정 · 📖 약 1분 · 309자/단어 #python #pandas #groupby #aggregation
Pandas groupby, groupby 집계, split-apply-combine

정의

DataFrame.groupby(key) 는 데이터를 그룹으로 나누고 (split), 각 그룹에 함수를 적용 (apply), 결과를 합쳐 (combine) 새 DataFrame 으로 만드는 split-apply-combine 패턴의 구현.

SQL 의 GROUP BY 와 같은 개념, 더 풍부한 API.

시각화

기본

df.groupby('city')['salary'].mean()
df.groupby('city')['salary'].sum()
df.groupby('city').agg({'salary': 'mean', 'age': 'max'})
df.groupby(['city', 'dept']).size()
python
import pandas as pd
df = pd.DataFrame({
  'city': ['Seoul', 'Busan', 'Seoul', 'Busan', 'Seoul'],
  'dept': ['A', 'A', 'B', 'B', 'A'],
  'salary': [3000, 4000, 5000, 4500, 3500],
})
print(df.groupby('city')['salary'].mean())
결과
city
Busan    4250.0
Seoul    3833.333333
Name: salary, dtype: float64
citysalary mean
Busan4250.00
Seoul3833.33

여러 컬럼 그룹

df.groupby(['city', 'dept'])['salary'].mean()
python
import pandas as pd
df = pd.DataFrame({
  'city': ['Seoul', 'Busan', 'Seoul', 'Busan', 'Seoul'],
  'dept': ['A', 'A', 'B', 'B', 'A'],
  'salary': [3000, 4000, 5000, 4500, 3500],
})
print(df.groupby(['city', 'dept'])['salary'].mean())
결과
city   dept
Busan  A       4000.0
     B       4500.0
Seoul  A       3250.0
     B       5000.0
Name: salary, dtype: float64

결과는 MultiIndex Series. .reset_index() 또는 .unstack() 으로 평탄화.

agg 로 여러 함수

df.groupby('city').agg({
    'salary': ['mean', 'sum', 'max'],
    'age': 'mean',
})

Pandas agg 참고.

자주 쓰는 메서드

메서드의미
.sum(), .mean(), .median(), .std()통계
.min(), .max()극값
.count()non-null 개수
.size()그룹별 행 수 (NaN 포함)
.first(), .last(), .nth(i)위치 기반
.head(n), .tail(n)그룹 내 상위/하위 N
.cumsum(), .cumcount()누적
.transform(fn)그룹별 변환, 원본 shape 유지
.apply(fn)임의 함수, 가장 유연
.filter(fn)그룹 단위 필터

groupby 결과는 lazy

g = df.groupby('city')      # GroupBy 객체만, 아직 계산 안 함
g.groups                     # {'Seoul': [0, 2, 4], 'Busan': [1, 3]}
g.get_group('Seoul')         # 한 그룹의 DataFrame
list(g)                      # [(name, df), ...]

명시적으로 집계 함수를 호출해야 계산 발생.

그룹별 정렬 후 head (top N per group)

df.sort_values(['city', 'salary'], ascending=[True, False]) \
   .groupby('city').head(2)

각 city 별 salary 상위 2 명.

그룹별 정규화 (transform)

df['salary_z'] = df.groupby('dept')['salary'].transform(
    lambda x: (x - x.mean()) / x.std()
)

각 부서 내에서 z-score, 원본 DataFrame 의 shape 유지.

함정

1. as_index 의 의미

df.groupby('city')['salary'].mean()             # MultiIndex Series
df.groupby('city', as_index=False)['salary'].mean()   # DataFrame, city 가 컬럼

2. NaN 그룹

기본은 NaN 그룹 제외. dropna=False 로 포함 가능.

df.groupby('city', dropna=False)['salary'].mean()

3. groupby + apply 의 느림

df.groupby('x').apply(complex_function)
# apply 는 가장 느림, 가능하면 agg / transform / 벡터 연산

4. SettingWithCopyWarning

group = df.groupby('city').get_group('Seoul')
group['new'] = 1     # ⚠️
group = group.copy()

참고

이 글의 용어 (4개)
[Pandas] agg / aggregatepandas
정의 는 여러 집계 함수를 한 번에 적용 한다. , , 모두에서 사용 가능. 는 같은 함수의 별칭. 다양한 형태 단일 함수 함수 리스트 <CodeWithOutput languag…
[Pandas] DataFramepandas
정의 은 2차원 레이블 테이블. 각 열이 , 모든 열이 같은 (행 라벨) 를 공유. SQL 테이블 / Excel 시트 / R data.frame 의 Python 대응체. 생성 <…
[Pandas] pivot_tablepandas
정의 는 의 확장. 집계 함수를 동반 해 중복 (index, columns) 도 처리. Excel 의 피벗 테이블과 가장 가까운 기능. 기본 <CodeWithOutput lang…
[Pandas] transform / applypandas
정의 | 메서드 | 입력 | 출력 | 용도 | |:---|:---|:---|:---| | | 그룹 | 같은 shape | 정규화, 보충 | | | 그룹 | 임의 shape | 가…

💬 댓글

사이트 검색 / 명령어

검색

스크롤 = 확대/축소 · 드래그 = 이동 · 0 = 원래 크기 · ESC = 닫기