카테고리 없음
3. <Pandas> 그룹연산과 변형 transform()/apply()/cut()/qcut()/pivot()/crosstab()
Mr.jjong
2017. 4. 24. 16:58
In [2]:
#본 실습내용은 출판사 O'REILLY의 Pyton for Data Analisys를 참고하여 만들었음을 말씀드립니다.
from numpy.random import randn
import numpy as np
import os
import matplotlib.pyplot as plt
from pandas import Series, DataFrame
import pandas as pd
In [46]:
tips = pd.read_csv('tips.csv')
tips = tips.sample(10)
tips
Out[46]:
그룹별 연산과 변형¶
- transform() 인자: 스칼라 값이나 같은 크기를 가지는 배열을 반환하는 함수
- apply() 인자: pandas 객체나 스칼라 값을 반환하는 함수
- apply: 분리 - 적용 - 병합
- 그룹 색인 생략하기
- 변위치 분석과 버킷 분석
- 그룹에 국한된 값으로 누락된 값 채우기
add_prefix()¶
In [70]:
tip_means = tips.groupby('sex').mean().add_prefix('mean_')
tip_means
Out[70]:
transform() 은 들어온 메서드에 대해 각 원소를 살리고 그 안에 연산결과를 채운다.¶
In [71]:
tips.groupby('day').transform(np.mean)
Out[71]:
apply() 함수는 그룹별로 행당 한줄의 정리된 결과값으로 정리되어 출력된다.¶
In [72]:
tips.groupby('day').apply(np.mean)
Out[72]:
1. apply: 분리 - 적용 - 병합¶
In [73]:
tips['pct']= tips['tip']/tips['total_bill']*100 # 팁 비율에 대해 추가.
tips
Out[73]:
In [74]:
def top (df,n=5,column = 'pct'): #함수 설명 : 인자는 데이터프레임(df),갯수(n),컬럼이름(column)을 받는다.
return df.sort_values(by=column)[-n:] #그중 해당칼럼의 상위 n개의 로우를 반환한다.
top(tips,n=6)
Out[74]:
In [75]:
tips.groupby('smoker').apply(top) #top 함수에 아무런 인자(parameter)를 주지 않았음으로 pct에서 상위5개 추출
Out[75]:
In [76]:
tips.groupby('smoker').apply(top,n=1,column='total_bill') # total_bill에서 상위 1개씩 뽑아내기
Out[76]:
In [77]:
tips.groupby('smoker',group_keys=False).apply(top)
Out[77]:
In [78]:
tips.groupby('smoker',group_keys=False).apply(top).describe()
Out[78]:
cut() : 지정된 칼럼의 최솟값과 최댓값을 등분위로 나누는 메서드¶
In [79]:
factor_cut = pd.cut(tips['tip'],4)
factor_cut # 4등분된 크기로 각 로우마다 카테고리화된 값들이 나열되어 있다.
Out[79]:
In [80]:
tips.groupby(factor_cut).agg(['size','mean']) # 지난 포스트에서 배웠듯이, groupby에 로우의 수와 같은 array를 넣어주면
# 행당 키에 맞게 그룹화시키고 이에 대한 size, mean값을 구한 것이다.
Out[80]:
위 결과값을 보면 데이터 크기들 4등분 하였음으로 size가 각 그룹마다 다른 것을 볼 수 있다.¶
그렇다면 데이터 갮을 4등분하는 것이 아니라 데이터의 갯수를 4등분 할 수 는 없을까? 이를 위해서 qcou()이라는 메서드를 사용할 수 있다.
qcut() : 주어진 데이터의 갯수를 n등분하는 메서드¶
In [81]:
tips
Out[81]:
In [82]:
factor_qcut = pd.qcut(tips.total_bill, 5,labels=False)
factor_qcut.value_counts()
factor_qcut
Out[82]:
In [83]:
factor_qcut = pd.qcut(tips.tip, 5,labels=False)
factor_qcut
Out[83]:
In [84]:
tips.groupby(factor_qcut).agg(['size','mean'])
Out[84]:
In [85]:
S= Series(np.random.randn(6))
S[::2]=np.nan
S
Out[85]:
In [86]:
S.fillna(S.mean()) # Nan 이었던 부분이 S의 평균으로 채워진 것을 볼 수 있다.
Out[86]:
In [87]:
#그룹별 NaN 채우기 예제
states = ['Ohio', 'New York', 'Vermont', 'Florida',
'Oregon', 'Nevada', 'California', 'Idaho']
group_key = ['East'] * 4 + ['West'] * 4
data = Series(np.random.randn(8), index=states)
data[['Vermont', 'Nevada', 'Idaho']] = np.nan
data
Out[87]:
In [88]:
data.groupby(group_key).mean()
Out[88]:
In [89]:
fill_mean = lambda g : g.fillna(g.mean())
In [90]:
data.groupby(group_key).apply(fill_mean)
Out[90]:
In [91]:
# 그룹에 따라 정의된 값 채우기
# group의 name 속성 이용
# group_key = ['East'] * 4 + ['West'] * 4
fill_values = {'East': 0.5, 'West': -1} #해당 컬럼이름의 사전형태로 채울 값을 설정해 놓는다.
fill_func = lambda g: g.fillna(fill_values[g.name])# g.name!!!!!이거 중요!! 사전에 g.name을 넣어 값을 갖고온다
data.groupby(group_key).apply(fill_func)
Out[91]:
피벗테이블과 교차일람표¶
데이터 요약화 도구 데이터를 하나 이상의 키로 수집해서 어떤 키는 로우에, 어떤 키는 칼럼에 나열해서 데이터를 정렬 DataFrame에 pivot_table() 또는 pandas.pivot_table pivot_table() margins=True는 부분합 추가 기능 제공 (groupby) pivot_table 옵션 [표9-2] 379p
1> 교차일람표¶
In [92]:
tips
Out[92]:
In [93]:
tips.pivot_table(index=['sex','smoker']) ## 기본적으로 pivot_table은 평균을 계산한다.
Out[93]:
In [94]:
tips.pivot_table(['tip','size'],index=['sex','smoker'],columns='time')
# [tip,size] 에 대해서만 인덱스를 sex와 smoker로 column은 time으로 평균을 구한다.
Out[94]:
In [95]:
tips.pivot_table(['tip','size'],index=['sex','smoker'],columns='time', margins=True)
# margine = True 로 놓으면 단일 행과 열에 대한 total 값을 붙여준다.
Out[95]:
In [96]:
tips.pivot_table(['tip','size'],index=['sex','smoker'],columns='time', margins=True, fill_value=0)
# NaN값을 지정된 값으로 채워줄 수 있다.
Out[96]:
In [97]:
tips.pivot_table(['tip','size'],index=['sex','smoker'],columns='time', margins=True, fill_value=0,aggfunc='sum')
Out[97]:
2.교차일람표 crosstab¶
그룹 빈도 계산하기 위한 피벗 테이블의 특수한 경우 pandas의 crosstab() 인자: 배열이나 Series, 배열의 리스트
In [99]:
pd.crosstab([tips.time,tips.day],tips.smoker, margins=True)
Out[99]:
In [ ]: