2025.02.24 - [프로그래밍/Python 관련 정보] - [Pandas] Table of Contents
Groupby 후 추가적인 기능을 달아서 사용할 수도 있습니다. agg는 Groupby 포스팅에서 상세히 다루었기 때문에 이 부분은 제외하고 나머지 transform, filter, apply에 대해서 알아보겠습니다.
1. Transform
가끔 데이터프레임에서 연산을 수행하다가 그룹별로 연산을 수행하되 원본 데이터의 행(크기)은 유지한채 남겨두고 싶을 때가 있습니다(=그룹별 연산 후 결과를 원본 row 개수와 동일하게 반환). SQL로 비교하자면 Partition by 를 통해 계산하는 Window함수를 상상하시면 되고, Tableau를 생각하면 VLOD연산에서 Exclude 연산을 생각하시면 되겠습니다.
이러한 작업을 Pandas에서 진행하려면 transform 함수를 사용하면 됩니다. syntax는 아래와 같습니다.
df['변환된 값'] = df.groupby('그룹')['대상 열'].transform(함수)
import pandas as pd
data = {
'카테고리': ['A', 'B', 'A', 'B', 'C', 'A', 'C'],
'값1': [10, 20, 30, 40, 50, 60, 70],
'값2': [100, 200, 300, 400, 500, 600, 700]
}
df = pd.DataFrame(data)
print(df)
카테고리 값1 값2
0 A 10 100
1 B 20 200
2 A 30 300
3 B 40 400
4 C 50 500
5 A 60 600
6 C 70 700
몇 가지 연산 예시를 한번 수행해보겠습니다.
1) 그룹별 평균 값을 계산
df['카테고리별 값1 평균'] = df.groupby('카테고리')['값1'].transform('mean')
print(df)
카테고리 값1 값2 카테고리별 값1 평균
0 A 10 100 33.333333
1 B 20 200 30.000000
2 A 30 300 33.333333
3 B 40 400 30.000000
4 C 50 500 60.000000
5 A 60 600 33.333333
6 C 70 700 60.000000
보시는 것처럼 groupby를 시킨 카테고리 별로 같은 값을 가지는 것을 확인할 수 있습니다.
2) 그룹 별 최대값에서의 이격을 계산
df['값1 최대값 차이'] = df.groupby('카테고리')['값1'].transform(lambda x: x.max() - x)
print(df)
카테고리 값1 값2 값1 최대값 차이
0 A 10 100 50
1 B 20 200 20
2 A 30 300 30
3 B 40 400 0
4 C 50 500 20
5 A 60 600 0
6 C 70 700 0
3) 그룹 별 누적 합 계산
df['값1 그룹별 누적 합'] = df.groupby('카테고리')['값1'].transform('cumsum')
print(df)
카테고리 값1 값2 값1 그룹별 누적 합
0 A 10 100 10
1 B 20 200 20
2 A 30 300 40
3 B 40 400 60
4 C 50 500 50
5 A 60 600 100
6 C 70 700 120
2. Filter
그룹 별 통계량이 특정 조건을 만족하는 그룹만 추출하고자 할 때 쓰는 기능입니다. 자꾸 SQL에 비유해서 설명하는데, 제가 느끼기엔 이건 SQL group by 후 Having 조건을 주는 것과 비슷하겠네요(물론 Group화 된 상태에서 출력되는 것이 아니라 groupby화 전 필터링이라는 부분이 다르긴 합니다).
df = pd.DataFrame({
'dept': ['A', 'A', 'B', 'B', 'B'],
'sales': [100, 150, 200, 130, 170]
})
df['mean_sales'] = df.groupby('dept')['sales'].transform('mean')
dept sales mean_sales
0 A 100 125.0
1 A 150 125.0
2 B 200 166.6667
3 B 130 166.6667
4 B 170 166.6667
df_filtered = df.groupby('dept').filter(lambda x: x['sales'].mean() > 150)
dept sales mean_sales
2 B 200 166.6667
3 B 130 166.6667
4 B 170 166.6667
3. Apply
다들 아시다시피 Groupby와 함께 쓰지 않고 단독으로도 사용되는 기능입니다. 그룹 별로 함수를 적용할 때 그 유연성을 극대화할 수 있는 도구입니다. transform은 shape이 엄격하게 유지된다면 apply의 경우에는 사용 방식에 따라 다양한 결과물이 나올 수 있습니다.
df_applied = df.groupby('dept').apply(lambda x: x.sort_values('sales', ascending=False))
print(df_applied)
dept sales mean_sales
dept
A 1 A 150 125.0
0 A 100 125.0
B 2 B 200 166.6667
4 B 170 166.6667
3 B 130 166.6667
df = pd.DataFrame({
'dept': ['A', 'A', 'B', 'B', 'B'],
'sales': [100, 150, 200, 130, 170],
'name': ['Kim', 'Lee', 'Park', 'Choi', 'Jung']
})
dept sales name
0 A 150 Lee
1 A 100 Kim
2 B 200 Park
3 B 170 Jung
예) 그룹별 Top-N뽑기
top2 = df.groupby('dept').apply(lambda x: x.nlargest(2, 'sales')).reset_index(drop=True)
dept sales name
0 A 150 Lee
1 A 100 Kim
2 B 200 Park
3 B 170 Jung
'프로그래밍 > Python 관련 정보' 카테고리의 다른 글
[Pandas] pandas.Series.dt (일자와 시간 처리) (1) | 2025.02.11 |
---|---|
[Algorithm] Depth/Breadth First Search (0) | 2025.02.11 |
[Pandas] groupby + agg 의 활용 (0) | 2025.02.05 |
[Python Programming 기초] Copy의 종류 (0) | 2025.02.05 |
[Python - Frequently Used Code] pandas DataFrame 문자열 대체 (0) | 2025.02.04 |