Py) 기초 - Pandas(피보팅)

Py) 기초 - Pandas(피보팅)

파이썬 기반 데이터분석을 위하여 Pandas 라이브러리의 데이터프레임 객체의 피보팅에 대해 알아보고자 한다.


개요

엑셀에는 피벗테이블이라는 도구가 있다. 피벗테이블은 행과 열에 기준이 되는 변수를 지정하여 입맛에 맞게 값을 다양한 방식으로 요약하기 쉽게 도와주는 도구이다.
엑셀 피벗테이블 설정창

해당 기능처럼 데이터를 처리할 수 있는 데이터프레임 객체의 메서드로 언급되는 대표적인 메서드가 .pivot().pivot_table() 이다. 그리고 비슷한 기능을 하는 메서드가 .melt()가 있고 함수는 crosstab()이 있다.
※ 관련 게시물: Pandas(Crosstab)
※ 관련 게시물: Pandas(Melt)

.pivot().pivot_table() 메서드는 Long Form과 Wide From 같이 특정 자료구조에 구애받지 않고 비교적 자유롭게 결과를 산출할 수 있다. 사용하다 보면 crosstab() 함수와 .pivot_table() 메서드가 매우 유사하다고 생각될것이다. 해당 함수와 메서드는 공통적으로 특정 변수(2개 이상)를 기준으로 대상 변수를 요약하는 것인데 crosstab() 함수는 비율계산과 변수별 합산을 지원하고, .pivot_table() 메서드는 결측치 처리가 조금 쉽다. 그래서 사실 본인은 crosstab() 함수를 더 선호한다.

실습

실습을 위해 다음과 같은 데이터를 준비한다.

1
2
3
4
5
6
7
df = pd.DataFrame({"지점": ["A", "A", "B", "B"],
"상품": ["P1", "P2", "P1", "P2"],
"Q1": [112, 134, 156, 178],
"Q2": [212, 234, 256, 278],
"Q3": [312, 334, 356, 378],
"Q4": [412, 434, 456, 478]})
df
지점 상품 Q1 Q2 Q3 Q4
0 A P1 112 212 312 412
1 A P2 134 234 334 434
2 B P1 156 256 356 456
3 B P2 178 278 378 478

.pivot()

연산을 하지 않고 자료구조만 변경하는 .pivot() 을 알아보자.
지점별 상품별 1분기(Q1) 판매실적을 Wide Form으로 정리하고자 한다면 다음과 같다.

1
df.pivot(index = "지점", columns = "상품", values = "Q1")
상품 P1 P2
지점
A 112 134
B 156 178

.pivot_table() 기본

.pivot()에서 연산이 가미된 .pivot_table() 을 알아보기 위해 이전 게시글에서 언급한 .melt() 메서드를 사용하여 Long Form 데이터 객체 “df_melt”를 생성해보자.
※ 관련 게시물: Pandas(Melt)

1
2
3
4
df_melt = df.melt(id_vars = ["지점", "상품"], 
var_name = "분기",
value_name = "매출")
df_melt.head()
지점 상품 분기 매출
0 A P1 Q1 112
1 A P2 Q1 134
2 B P1 Q1 156
3 B P2 Q1 178
4 A P1 Q2 212

지점별 분기별 매출 평균을 보고자 한다면 다음과 같이 작성할 수 있다.

1
2
df_melt.pivot_table(index = "지점", columns = "분기", values = "매출",
aggfunc = "mean")
분기 Q1 Q2 Q3 Q4
지점
A 123 223 323 423
B 167 267 367 467

상기 결과는 다음과 같이 .groupby() 메서드를 사용한 것과 유사하다. 엄밀하게 말해서 자료구조만 다르다.

1
df_melt.groupby(["지점", "분기"])["매출"].mean().reset_index()
지점 분기 매출
0 A Q1 123.0
1 A Q2 223.0
2 A Q3 323.0
3 A Q4 423.0
4 B Q1 167.0
5 B Q2 267.0
6 B Q3 367.0
7 B Q4 467.0

그리고 기준 변수를 어느 인자에 할당하느냐에 따라 그 결과가 달라지니 참고하도록 하자.

1
2
df_melt.pivot_table(index = "분기", columns = "지점", values = "매출",
aggfunc = "mean")
지점 A B
분기
Q1 123 167
Q2 223 267
Q3 323 367
Q4 423 467

.pivot_table() 사용자 정의 함수

기존의 메서드가 지원하지 않는 범위의 연산을 실시할 경우 사용자 정의 함수를 다음과 같이 사용할 수 있다.

1
2
3
4
5
def mean_10000(x):
return x.mean() + 10000

df_melt.pivot_table(index = "상품", columns = "지점", values = "매출",
aggfunc = mean_10000)
지점 A B
상품
P1 10262 10306
P2 10284 10328

.pivot_table() lambda 함수

한 줄로 끝나는 정도로 사용자 정의 함수보다 훨씬 간결하고 일회성으로 사용하는 연산규칙이라면 lambda 함수를 다음과 같이 사용해볼 수 있다.

1
2
df_melt.pivot_table(index = "상품", columns = "지점", values = "매출",
aggfunc = lambda x: x.mean() + 10000)
지점 A B
상품
P1 10262 10306
P2 10284 10328
Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×