[Python pandas] 데이터 재구조화 (reshaping) : data.pivot(), pd.pivot_table(data)
Python 분석과 프로그래밍/Python 데이터 전처리 2016. 12. 23. 23:44분석을 하다 보면 원본 데이터의 구조가 분석 기법에 맞지 않아서 행과 열의 위치를 바꾼다거나, 특정 요인에 따라 집계를 해서 구조를 바꿔주어야 하는 경우가 있습니다.
이번 포스팅부터는 이처럼 데이터 재구조화(reshaping data)를 위해 사용할 수 있는 Python pandas의 함수들에 대해서 아래의 순서대로 나누어서 소개해보겠습니다.
- (1) pivot(), pd.pivot_table()
이번 포스팅에서는 첫번째로 data.pivot(), pd.pivot_table(data)에 대해서 알아보겠습니다.
먼저, 필요한 모듈을 불러오고, 간단한 예제 데이터셋을 만들어보겠습니다. 고객ID(cust_id), 상품 코드(prod_cd), 등급(grade), 구매금액(pch_amt) 의 4개 변수로 이루어진 데이터 프레임입니다.
# importing libraries
In [1]: import numpy as np In [2]: import pandas as pd In [3]: from pandas import DataFrame
# making an example DataFrame In [4]: data = DataFrame({'cust_id': ['c1', 'c1', 'c1', 'c2', 'c2', 'c2', 'c3', 'c3', 'c3'], ...: 'prod_cd': ['p1', 'p2', 'p3', 'p1', 'p2', 'p3', 'p1', 'p2', 'p3'], ...: 'grade' : ['A', 'A', 'A', 'A', 'A', 'A', 'B', 'B', 'B'], ...: 'pch_amt': [30, 10, 0, 40, 15, 30, 0, 0, 10]}) ...: In [5]: data Out[5]: cust_id grade pch_amt prod_cd
|
위의 data 예제처럼 위에서 아래로 길게 늘어서 있는 데이터셋을 행(row)에는 고객ID(cust_id), 열(column)에는 상품코드(prd_cd), 행과 열이 교차하는 칸에는 구매금액(pch_amt)이 위치하도록 데이터를 구조를 바꿔보겠습니다. 말로 설명해도 이해가 잘 안될 수 있는데요, 아래 data.pivot(index, columns, values) 예시를 보시지요.
(1) 데이터 재구조화 : data.pivot(index, columns, values) |
# reshaping DataFrame by pivoting
In [6]: data_pivot = data.pivot(index='cust_id', columns='prod_cd', values='pch_amt') In [7]: data_pivot Out[7]: prod_cd p1 p2 p3
|
(2) 데이터 재구조화 : pd.pivot_table(data, index, columns, values, aggfunc) |
위의 data.pivot() 과 동일한 결과가 나오도록 데이터를 재구조화하는데 pd.pivot_table()을 사용할 수도 있습니다.
# pd.pivot_table(data, index, columns, values, aggfunc)
In [8]: pd.pivot_table(data, index='cust_id', columns='prod_cd', values='pch_amt') Out[8]: prod_cd p1 p2 p3
|
data.pivot() 로 하면 에러가 나서 안되고, pivot_table(data) 을 사용해야만 하는 경우가 몇 가지 있습니다. 그러므로 여러가지 외우는거 싫고, 헷갈리는거 싫어하는 분이라면 pivot_table() 사용법만 잘 숙지하는 것도 좋은 방법입니다.
아래에 pivot()으로는 안되고 pivot_table()은 되는 경우를 나란히 이어서 제시해보겠습니다.
(a) index 가 2개 이상인 경우입니다.
# pivot() with 2 indices :ValueError
In [9]: data.pivot(index=['cust_id', 'grade'], columns='prod_cd', values='pch_amt') ValueError: Wrong number of items passed 9, placement implies 2
# pd.pivot_table() with 2 indices : works well!
In [10]: pd.pivot_table(data, index=['cust_id', 'grade'], columns='prod_cd', values='pch_amt') Out[10]: prod_cd p1 p2 p3
|
(b) columns 가 2개 이상인 경우 입니다.
# pivot() with 2 columns : KeyError
In [11]: data.pivot(index='cust_id', columns=['grade', 'prod_cd'], values='pch_amt') KeyError: 'Level grade not found'
# pd.pivot_table() with 2 columns : works well! In [12]: pd.pivot_table(data, index='cust_id', columns=['grade', 'prod_cd'], values='pch_amt') Out[12]: grade A B grade A B
|
pivot() 함수는 중복값이 있을 경우 ValueError를 반환합니다. 반면에, pd.pivot_table()은 aggfunc=np.sum 혹은 aggfunc=np.mean 과 같이 집계(aggregation)할 수 있는 함수를 제공함에 따라 index 중복값이 있는 경우에도 문제가 없습니다.
# pivot() with index which contains duplicate entries: ValueError In [13]: data.pivot(index='grade', columns='prod_cd', values='pch_amt') ValueError: Index contains duplicate entries, cannot reshape
# pd.pivot_table() with aggfunc : works well!
In [14]: pd.pivot_table(data, index='grade', columns='prod_cd', ...: values='pch_amt', aggfunc=np.sum) Out[14]: prod_cd p1 p2 p3
In [15]: pd.pivot_table(data, index='grade', columns='prod_cd', ...: values='pch_amt', aggfunc=np.mean) Out[15]: prod_cd p1 p2 p3
In [16]: pd.pivot_table(data, index='grade', columns='prod_cd', values='pch_amt') Out[16]: prod_cd p1 p2 p3
|
pd.pivot_table()은 margins=True 옵션을 설정해주면 행과 열을 기준으로 합계(All, row sum, column sum)를 같이 제시해주기 때문에 꽤 편리합니다
# pd.pivot_table : margins=True
In [17]: pd.pivot_table(data, index='grade', columns='prod_cd', ...: values='pch_amt', aggfunc=np.sum, margins=True) Out[17]: prod_cd p1 p2 p3 All
In [18]: pd.pivot_table(data, index='grade', columns='prod_cd', ...: values='pch_amt', aggfunc=np.mean, margins=True) Out[18]: prod_cd p1 p2 p3 All
|
이상으로 data.pivot(), pd.povit_table(data)를 활용한 데이터 재구조화 소개를 마치겠습니다.
다음번 포스팅에서는 stack(), unstack()을 이용한 데이터 재구조화에 대해서 알아보겠습니다.
많은 도움 되었기를 바랍니다.