
가장 자주 쓰는 건 agg(), size(), transform(), unstack()
# 각 그룹의 행 개수
df.groupby('category').size()
# 예시
sales = pd.DataFrame({
'category': ['A', 'A', 'B', 'B', 'B'],
'amount': [100, 200, 150, 300, 250]
})
sales.groupby('category').size()
# category
# A 2
# B 3
# 각 컬럼의 non-NaN 개수
df.groupby('category').count()
# NaN이 있는 경우
df = pd.DataFrame({
'category': ['A', 'A', 'B', 'B'],
'value': [1, None, 3, 4]
})
df.groupby('category').count()
# category value
# A 1 (NaN 제외)
# B 2
# 각 그룹의 합
df.groupby('category')['amount'].sum()
# 여러 컬럼
df.groupby('category')[['amount', 'quantity']].sum()
# 예시
sales.groupby('category')['amount'].sum()
# category
# A 300
# B 700
# 평균
df.groupby('category')['amount'].mean()
sales.groupby('category')['amount'].mean()
# category
# A 150.0
# B 233.3
# 최대값
df.groupby('category')['amount'].max()
# 최소값
df.groupby('category')['amount'].min()
# 여러 통계 한 번에
df.groupby('category')['amount'].agg(['min', 'max', 'mean'])
# 중앙값
df.groupby('category')['amount'].median()
# 표준편차
df.groupby('category')['amount'].std()
# 분산
df.groupby('category')['amount'].var()
df.groupby('category')['amount'].agg(['sum', 'mean', 'count', 'std'])
# 결과:
# category sum mean count std
# A 300 150.0 2 70.7
# B 700 233.3 3 76.4
df.groupby('category').agg({
'amount': ['sum', 'mean'],
'quantity': ['count', 'max'],
'price': 'median'
})
# 사용자 정의 함수
df.groupby('category')['amount'].agg(lambda x: x.max() - x.min())
# 이름 지정
df.groupby('category')['amount'].agg(
total='sum',
average='mean',
range=lambda x: x.max() - x.min()
)
# 각 그룹의 평균을 원본 크기로 브로드캐스트
df['group_mean'] = df.groupby('category')['amount'].transform('mean')
# 예시
sales['category_avg'] = sales.groupby('category')['amount'].transform('mean')
print(sales)
# category amount category_avg
# 0 A 100 150.0
# 1 A 200 150.0
# 2 B 150 233.3
# 3 B 300 233.3
# 4 B 250 233.3
# 그룹 평균으로 정규화
df['normalized'] = df.groupby('category')['amount'].transform(
lambda x: (x - x.mean()) / x.std()
)
# 각 그룹에 함수 적용
df.groupby('category').apply(lambda x: x.nlargest(2, 'amount'))
# 복잡한 연산
def custom_func(group):
return pd.Series({
'total': group['amount'].sum(),
'count': len(group),
'avg': group['amount'].mean()
})
df.groupby('category').apply(custom_func)
# 조건을 만족하는 그룹만 유지
# 평균이 200 이상인 그룹만
df.groupby('category').filter(lambda x: x['amount'].mean() > 200)
# 예시: 2개 이상의 항목이 있는 그룹만
df.groupby('category').filter(lambda x: len(x) >= 2)
# 각 그룹의 첫 번째 행
df.groupby('category').first()
# 마지막 행
df.groupby('category').last()
# 특정 컬럼만
df.groupby('category')['date'].first()
# 각 그룹의 첫 번째 항목
df.groupby('category').nth(0)
# 두 번째 항목
df.groupby('category').nth(1)
# 마지막 항목
df.groupby('category').nth(-1)
# 여러 개
df.groupby('category').nth([0, -1]) # 첫 번째와 마지막
# 그룹 내 누적 합
df['cumsum'] = df.groupby('category')['amount'].cumsum()
# 그룹 내 순번 (0부터 시작)
df['row_num'] = df.groupby('category').cumcount()
# 그룹 내 누적 개수
df['cumcount'] = df.groupby('category')['amount'].cumcount() + 1
# 예시
sales['cumulative'] = sales.groupby('category')['amount'].cumsum()
sales['rank'] = sales.groupby('category').cumcount() + 1
print(sales)
# category amount cumulative rank
# 0 A 100 100 1
# 1 A 200 300 2
# 2 B 150 150 1
# 3 B 300 450 2
# 4 B 250 700 3
# 그룹 내 순위
df['rank'] = df.groupby('category')['amount'].rank(ascending=False)
# 순위 방법 지정
df['rank'] = df.groupby('category')['amount'].rank(method='dense')
# method 옵션:
# - 'average': 동점자 평균 순위
# - 'min': 동점자 최소 순위
# - 'max': 동점자 최대 순위
# - 'first': 먼저 나온 순서
# - 'dense': 빈틈없는 순위
# 그룹 내에서 이전 값
df['prev_amount'] = df.groupby('category')['amount'].shift(1)
# 다음 값
df['next_amount'] = df.groupby('category')['amount'].shift(-1)
# 차이 계산
df['diff'] = df.groupby('category')['amount'].diff()
# 각 그룹에서 상위 2개
df.groupby('category').apply(lambda x: x.nlargest(2, 'amount'))
# 각 그룹에서 하위 1개
df.groupby('category').apply(lambda x: x.nsmallest(1, 'amount'))
grouped = df.groupby('category')
# 특정 그룹만 가져오기
group_a = grouped.get_group('A')
print(group_a)
import pandas as pd
# 샘플 데이터
qrels = pd.DataFrame({
'query_id': [1, 1, 1, 2, 2, 3, 3, 3, 3],
'doc_id': [101, 102, 103, 201, 202, 301, 302, 303, 304],
'relevance': [3, 2, 1, 3, 0, 2, 2, 1, 3]
})
# 쿼리별 통계
query_stats = qrels.groupby('query_id')['relevance'].agg([
('count', 'count'),
('mean', 'mean'),
('max', 'max'),
('min', 'min'),
('std', 'std')
]).round(2)
print(query_stats)
# count mean max min std
# query_id
# 1 3 2.00 3 1 1.00
# 2 2 1.50 3 0 2.12
# 3 4 2.00 3 1 0.82
train_qrels = pd.DataFrame({
'query_id': [1, 1, 1, 2, 2, 3],
'doc_id': [101, 102, 103, 201, 202, 301],
'label': ['E', 'S', 'C', 'E', 'E', 'S']
})
# 레이블별 개수
label_dist = train_qrels.groupby('label').size()
print(label_dist)
# label
# C 1
# E 3
# S 2
# 쿼리-레이블 조합
query_label = train_qrels.groupby(['query_id', 'label']).size().unstack(fill_value=0)
print(query_label)
# label C E S
# query_id
# 1 1 1 1
# 2 0 2 0
# 3 0 0 1
logs = pd.DataFrame({
'user_id': [1, 1, 1, 2, 2, 2],
'timestamp': pd.date_range('2025-01-01', periods=6, freq='H'),
'action': ['login', 'view', 'logout', 'login', 'click', 'logout']
})
# 사용자별 첫 로그인 시간
logs.groupby('user_id')['timestamp'].first()
# 사용자별 활동 개수
logs.groupby('user_id').size()
# 사용자별 마지막 활동
logs.groupby('user_id').last()
sales = pd.DataFrame({
'date': pd.date_range('2025-01-01', periods=10),
'category': ['A', 'B'] * 5,
'amount': [100, 150, 200, 180, 120, 160, 140, 190, 110, 170]
})
# 카테고리별 누적 합
sales['cumsum'] = sales.groupby('category')['amount'].cumsum()
# 카테고리별 이동 평균 (3일)
sales['rolling_avg'] = sales.groupby('category')['amount'].transform(
lambda x: x.rolling(3, min_periods=1).mean()
)
# 카테고리 내 순위
sales['rank'] = sales.groupby('category')['amount'].rank(ascending=False)
print(sales)
# 조건을 만족하는 행만 집계
df.groupby('category').apply(
lambda x: x[x['amount'] > 100]['amount'].sum()
)
# 그룹별 최빈값
df.groupby('category')['product'].apply(lambda x: x.mode()[0])
# 그룹별 고유값 개수
df.groupby('category')['product'].nunique()
# 1. 기본 집계
df.groupby('col').agg(['sum', 'mean', 'count'])
# 2. 여러 컬럼, 각각 다른 함수
df.groupby('col').agg({'col1': 'sum', 'col2': 'mean'})
# 3. 그룹 크기
df.groupby('col').size()
# 4. 피벗 테이블 스타일
df.groupby(['col1', 'col2']).size().unstack(fill_value=0)
# 5. 그룹별 변환 (원본 크기 유지)
df.groupby('col')['value'].transform('mean')
# 6. 그룹별 순위
df.groupby('col')['value'].rank(ascending=False)
# 7. 그룹별 누적
df.groupby('col')['value'].cumsum()
# 8. 상위 n개
df.groupby('col').apply(lambda x: x.nlargest(3, 'value'))
# 9. 조건 필터링
df.groupby('col').filter(lambda x: len(x) >= 5)
# 10. 커스텀 함수
df.groupby('col').apply(custom_function)