Pandas crosstab
Crosstab
crosstab은 범주형 변수 요인별로 교차분석하여 각 요인의 기준 별로 빈도를 세어서 도수분포표,교차표로 데이터를 재구조화 시켜주는 기능을 한다.
pivot table 의 한 유형이다.
parameter
기본적인 파라미터 구성은 다음과 같다.
사용법
데이터셋 불러오기
import pandas as pd
import numpy as np
list1 = ['정호','노제','노제','윈터','정호','노제','윈터','정호','노제','윈터','정호']
list2 = ['11/25','11/25','11/25','11/25','11/26','11/27','11/27','11/28','11/28','11/28','11/29']
list3 = ['아이폰','갤럭시','갤럭시','에어팟','에어팟','갤럭시','에어팟','아이폰','갤럭시','아이폰','에어팟']
list4 = [1,2,1,3,2,1,1,2,4,3,4]
df= pd.DataFrame({'판매원' : list1 , '판매날짜':list2 , '판매물품':list3, '판매개수':list4 })
df
판매원 | 판매날짜 | 판매물품 | 판매개수 | |
---|---|---|---|---|
0 | 정호 | 11/25 | 아이폰 | 1 |
1 | 노제 | 11/25 | 갤럭시 | 2 |
2 | 노제 | 11/25 | 갤럭시 | 1 |
3 | 윈터 | 11/25 | 에어팟 | 3 |
4 | 정호 | 11/26 | 에어팟 | 2 |
5 | 노제 | 11/27 | 갤럭시 | 1 |
6 | 윈터 | 11/27 | 에어팟 | 1 |
7 | 정호 | 11/28 | 아이폰 | 2 |
8 | 노제 | 11/28 | 갤럭시 | 4 |
9 | 윈터 | 11/28 | 아이폰 | 3 |
10 | 정호 | 11/29 | 에어팟 | 4 |
스우파의 노제님과 최강 걸그룹 에스파의 윈터님이 함께 하는 휴대폰 매장의 판매 장부 데이터이다.
기본 사용 법
날짜 별로 판매 여부를 파악해보자.
pd.crosstab(index= df.판매원 , columns = df.판매날짜)
판매날짜 | 11/25 | 11/26 | 11/27 | 11/28 | 11/29 |
---|---|---|---|---|---|
판매원 | |||||
노제 | 2 | 0 | 1 | 1 | 0 |
윈터 | 1 | 0 | 1 | 1 | 0 |
정호 | 1 | 1 | 0 | 1 | 1 |
날짜 별로 데이터가 존재하는지 여부에 따라 1과 0 으로 나타난다.
이번엔 날짜별로 누가 어떤 물품을 판매했는지 여부까지 파악해보자.
pd.crosstab(index= [df.판매원,df.판매물품] , columns = df.판매날짜)
판매날짜 | 11/25 | 11/26 | 11/27 | 11/28 | 11/29 | |
---|---|---|---|---|---|---|
판매원 | 판매물품 | |||||
노제 | 갤럭시 | 2 | 0 | 1 | 1 | 0 |
윈터 | 아이폰 | 0 | 0 | 0 | 1 | 0 |
에어팟 | 1 | 0 | 1 | 0 | 0 | |
정호 | 아이폰 | 1 | 0 | 0 | 1 | 0 |
에어팟 | 0 | 1 | 0 | 0 | 1 |
파라메터로 준 칼럼 순서대로 그룹화 하여 dataframe을 재구조화 해준다.
values 파라미터 사용
values 파라미터를 사용함으로서 수치형 데이터를 사용할 수 있다.
pd.crosstab(index= [df.판매원,df.판매물품] , columns = df.판매날짜, values= df.판매개수, aggfunc=np.sum)
판매날짜 | 11/25 | 11/26 | 11/27 | 11/28 | 11/29 | |
---|---|---|---|---|---|---|
판매원 | 판매물품 | |||||
노제 | 갤럭시 | 3.0 | NaN | 1.0 | 4.0 | NaN |
윈터 | 아이폰 | NaN | NaN | NaN | 3.0 | NaN |
에어팟 | 3.0 | NaN | 1.0 | NaN | NaN | |
정호 | 아이폰 | 1.0 | NaN | NaN | 2.0 | NaN |
에어팟 | NaN | 2.0 | NaN | NaN | 4.0 |
집계할 데이터가 존재하지 않는 부분은 NaN으로 표시된다.
주의할점은 values와 aggfunc은 항상 함께 쓰인다.
aggfunc이 없다면 오류가 난다.
NaN이 보기 싫다면 .fillna(0) 를 통해 제거할 수 있다.
pd.crosstab(index= [df.판매원,df.판매물품] , columns = df.판매날짜, values= df.판매개수, aggfunc=np.sum).fillna(0)
판매날짜 | 11/25 | 11/26 | 11/27 | 11/28 | 11/29 | |
---|---|---|---|---|---|---|
판매원 | 판매물품 | |||||
노제 | 갤럭시 | 3.0 | 0.0 | 1.0 | 4.0 | 0.0 |
윈터 | 아이폰 | 0.0 | 0.0 | 0.0 | 3.0 | 0.0 |
에어팟 | 3.0 | 0.0 | 1.0 | 0.0 | 0.0 | |
정호 | 아이폰 | 1.0 | 0.0 | 0.0 | 2.0 | 0.0 |
에어팟 | 0.0 | 2.0 | 0.0 | 0.0 | 4.0 |
총합 구하기
총합은 magins 파라미터를 이용해 표현할 수 있다.
pd.crosstab(index= [df.판매원,df.판매물품] , columns = df.판매날짜, values= df.판매개수, aggfunc=np.sum, margins=True).fillna(0)
판매날짜 | 11/25 | 11/26 | 11/27 | 11/28 | 11/29 | All | |
---|---|---|---|---|---|---|---|
판매원 | 판매물품 | ||||||
노제 | 갤럭시 | 3.0 | 0.0 | 1.0 | 4.0 | 0.0 | 8 |
윈터 | 아이폰 | 0.0 | 0.0 | 0.0 | 3.0 | 0.0 | 3 |
에어팟 | 3.0 | 0.0 | 1.0 | 0.0 | 0.0 | 4 | |
정호 | 아이폰 | 1.0 | 0.0 | 0.0 | 2.0 | 0.0 | 3 |
에어팟 | 0.0 | 2.0 | 0.0 | 0.0 | 4.0 | 6 | |
All | 7.0 | 2.0 | 2.0 | 9.0 | 4.0 | 24 |
인덱스와 칼럼의 끝에 총합에 대한 부분이 추가 된다.
이름 설정
각 파라미터의 이름을 설정해줄 있다.
pd.crosstab(index= [df.판매원,df.판매물품] , columns = df.판매날짜, values= df.판매개수, aggfunc=np.sum, margins=True
,rownames=["영업킹","기종"],colnames = ["Date"], margins_name="총합").fillna(0)
Date | 11/25 | 11/26 | 11/27 | 11/28 | 11/29 | 총합 | |
---|---|---|---|---|---|---|---|
영업킹 | 기종 | ||||||
노제 | 갤럭시 | 3.0 | 0.0 | 1.0 | 4.0 | 0.0 | 8 |
윈터 | 아이폰 | 0.0 | 0.0 | 0.0 | 3.0 | 0.0 | 3 |
에어팟 | 3.0 | 0.0 | 1.0 | 0.0 | 0.0 | 4 | |
정호 | 아이폰 | 1.0 | 0.0 | 0.0 | 2.0 | 0.0 | 3 |
에어팟 | 0.0 | 2.0 | 0.0 | 0.0 | 4.0 | 6 | |
총합 | 7.0 | 2.0 | 2.0 | 9.0 | 4.0 | 24 |
정규화
normalize=True 파라미터를 이용하여 총합을 1로 만들어 정규화를 할 수 있다.
pd.crosstab(index= [df.판매원,df.판매물품] , columns = df.판매날짜, values= df.판매개수, aggfunc=np.sum, margins=True
,rownames=["영업킹","기종"],colnames = ["Date"], margins_name="총합", normalize=True).fillna(0)
Date | 11/25 | 11/26 | 11/27 | 11/28 | 11/29 | 총합 | |
---|---|---|---|---|---|---|---|
영업킹 | 기종 | ||||||
노제 | 갤럭시 | 0.125000 | 0.000000 | 0.041667 | 0.166667 | 0.000000 | 0.333333 |
윈터 | 아이폰 | 0.000000 | 0.000000 | 0.000000 | 0.125000 | 0.000000 | 0.125000 |
에어팟 | 0.125000 | 0.000000 | 0.041667 | 0.000000 | 0.000000 | 0.166667 | |
정호 | 아이폰 | 0.041667 | 0.000000 | 0.000000 | 0.083333 | 0.000000 | 0.125000 |
에어팟 | 0.000000 | 0.083333 | 0.000000 | 0.000000 | 0.166667 | 0.250000 | |
총합 | 0.291667 | 0.083333 | 0.083333 | 0.375000 | 0.166667 | 1.000000 |
df2 =pd.crosstab(index= [df.판매원,df.판매물품] , columns = df.판매날짜, values= df.판매개수, aggfunc=np.sum, margins=True
,rownames=["영업킹","기종"],colnames = ["Date"], margins_name="총합", normalize=True).fillna(0)
round(df2*100,1)
Date | 11/25 | 11/26 | 11/27 | 11/28 | 11/29 | 총합 | |
---|---|---|---|---|---|---|---|
영업킹 | 기종 | ||||||
노제 | 갤럭시 | 12.5 | 0.0 | 4.2 | 16.7 | 0.0 | 33.3 |
윈터 | 아이폰 | 0.0 | 0.0 | 0.0 | 12.5 | 0.0 | 12.5 |
에어팟 | 12.5 | 0.0 | 4.2 | 0.0 | 0.0 | 16.7 | |
정호 | 아이폰 | 4.2 | 0.0 | 0.0 | 8.3 | 0.0 | 12.5 |
에어팟 | 0.0 | 8.3 | 0.0 | 0.0 | 16.7 | 25.0 | |
총합 | 29.2 | 8.3 | 8.3 | 37.5 | 16.7 | 100.0 |
위의 코드처럼 간단한 계산으로 백분위로 표현 할 수 있다.
댓글남기기