반응형
#!/usr/bin/env python
# coding: utf-8
# # Pandas IV: 그룹 연산
# In[ ]:
import numpy as np
#np.set_printoptions(precision=4, suppress=True)
import pandas as pd
#pd.options.display.max_rows = 20
import matplotlib.pyplot as plt
get_ipython().run_line_magic('matplotlib', 'inline')
plt.rc('figure', figsize=(10, 6))
from matplotlib import rcParams
rcParams['font.family'] = 'NanumGothic'
rcParams['font.size'] = 10
# # 1. GroupBy Mechanics
# ### 1.1 GroupBy
# In[ ]:
df = pd.DataFrame({'key1' : ['a', 'a', 'b', 'b', 'a'],
'key2' : ['one', 'two', 'one', 'two', 'one'],
'data1' : np.random.randn(5),
'data2' : np.random.randn(5)})
df
# #### Series Groupby
# In[ ]:
grouped = df['data1'].groupby(df['key1'])
grouped
# In[ ]:
grouped.mean()
# In[ ]:
# 2개의 키로 그룹핑
means = df['data1'].groupby([df['key1'], df['key2']]).mean()
means
# In[ ]:
means.unstack()
# In[ ]:
states = np.array(['Ohio', 'California', 'California', 'Ohio', 'Ohio'])
years = np.array([2005, 2005, 2006, 2005, 2006])
df['data1'].groupby([states, years]).mean()
# #### DataFrame Groupby
# In[ ]:
# key2: 숫자 컬럼이 아니어서 pandas가 제외 시킴
df.groupby('key1').mean()
# In[ ]:
df.groupby(['key1', 'key2']).mean()
# In[ ]:
df.groupby(['key1', 'key2']).size()
# ### 1.2 그룹간 순회
# In[ ]:
for name, group in df.groupby('key1'):
print(name)
print(group)
# In[ ]:
for (k1, k2), group in df.groupby(['key1', 'key2']):
print((k1, k2))
print(group)
# In[ ]:
pieces = dict(list(df.groupby('key1')))
pieces['b']
# #### 컬럼쪽 축으로 GroupBy
# In[ ]:
df
# In[ ]:
df.dtypes
# In[ ]:
grouped = df.groupby(df.dtypes, axis=1)
# In[ ]:
for dtype, group in grouped:
print(dtype)
print(group)
# ### 1.3 컬럼의 일부 선택
# 컬럼 선택
# ```python
# df.groupby('key1')['data1']
# df.groupby('key1')[['data2']]
# ```
# 관용적 표현
# ```python
# df['data1'].groupby(df['key1'])
# df[['data2']].groupby(df['key1'])
# ```
# In[ ]:
df.groupby(['key1', 'key2'])[['data2']].mean()
# In[ ]:
s_grouped = df.groupby(['key1', 'key2'])['data2']
s_grouped
s_grouped.mean()
# ### 1.4 사전과 Series에서 묶기
# In[ ]:
people = pd.DataFrame(np.random.randn(5, 5),
columns=['a', 'b', 'c', 'd', 'e'],
index=['Joe', 'Steve', 'Wes', 'Jim', 'Travis'])
people.iloc[2:3, [1, 2]] = np.nan # Add a few NA values
people
# In[ ]:
mapping = {'a': 'red', 'b': 'red', 'c': 'blue',
'd': 'blue', 'e': 'red', 'f' : 'orange'}
# In[ ]:
by_column = people.groupby(mapping, axis=1)
by_column.sum()
# In[ ]:
map_series = pd.Series(mapping)
map_series
# In[ ]:
people.groupby(map_series, axis=1).count()
# ### 1.5 함수로 묶기
# In[ ]:
people.groupby(len).sum()
# ### 1.6 여러가지 타입 혼합해서 묶기
# In[ ]:
key_list = ['one', 'one', 'one', 'two', 'two']
# In[ ]:
people.groupby([len, key_list]).min()
# ### 1.7 색인 단계로 묶기
# In[ ]:
columns = pd.MultiIndex.from_arrays([['US', 'US', 'US', 'JP', 'JP'],
[1, 3, 5, 1, 3]],
names=['cty', 'tenor'])
hier_df = pd.DataFrame(np.random.randn(4, 5), columns=columns)
hier_df
# In[ ]:
hier_df.groupby(level='cty', axis=1).count()
# ---
# # 2. 데이터 수집
# ### 2.1 집계함수 적용
# In[ ]:
df
# In[ ]:
grouped = df.groupby('key1')
grouped['data1'].quantile(0.9)
# In[ ]:
grouped.describe()
# #### groupby 메서드
#
# 함수 이름 | 설명
# :---|:---
# count | 그룹 내에 NA 값이 아닌 값의 수
# sum | NA 값이 아닌 값들의 합
# mean | NA 값이 아닌 값들의 평균
# median | NA 값이 아닌 값들의 산술 중간 값
# std, var | 표준편차와 분산 (n-1을 분모로 계산)
# min, max | NA 값이 아닌 값 중 최소 값, 최대 값
# prod | NA 값이 아닌 값의 곱
# first, last | NA 값이 아닌 값들 중 첫 번째 값, 마지막 값
# #### 사용자 함수 정의
# In[ ]:
def peak_to_peak(arr):
return arr.max() - arr.min()
# In[ ]:
grouped.agg(peak_to_peak)
# ### 2.2 컬럼에 여러 가지 함수 적용
# In[ ]:
tips = pd.read_csv('data/tips.csv')
# Add tip percentage of total bill
tips['tip_pct'] = tips['tip'] / tips['total_bill']
tips[:6]
# In[ ]:
grouped = tips.groupby(['day', 'smoker'])
# In[ ]:
# pandas에 정의된 기술 통계 함수는 함수 이름을 문자열로 입력
grouped_pct = grouped['tip_pct']
grouped_pct.agg('mean')
# In[ ]:
# 2개 이상의 함수 적용 (생성된 DataFrame의 컬럼이름은 함수이름으로 할당)
grouped_pct.agg(['mean', 'std', peak_to_peak])
# In[ ]:
# 2개 이상의 함수 적용시 생성된 DataFrame의 컬럼 이름 지정
grouped_pct.agg([('평균', 'mean'), ('표준편차', np.std)])
# In[ ]:
# 각 컬럼 별로 함수 적용
functions = ['count', 'mean', 'max']
result = grouped['tip_pct', 'total_bill'].agg(functions)
result
# In[ ]:
result['tip_pct']
# In[ ]:
# 생성된 DataFrame에 컬럼 이름 지정
ftuples = [('평균', 'mean'), ('분산', np.var)]
grouped['tip_pct', 'total_bill'].agg(ftuples)
# In[ ]:
# 계산할 컬럼과 적용할 함수를 각각 지정
grouped.agg({'tip' : np.max, 'size' : 'sum'})
# In[ ]:
# 계산할 컬럼과 적용할 함수들을 각각 지정
grouped.agg({'tip_pct' : ['min', 'max', 'mean', 'std'],
'size' : 'sum'})
# #### 인덱스 제거: reset_index() 와 동일
# In[ ]:
tips.groupby(['day', 'smoker'], as_index=False).mean()
# ---
# # 3. 그룹별 연산과 변형
# - 집계 - agg() : 적용함수는 스칼라값 반환
# - 변환 - transform(): 적용함수는 같은 크기를 가지는 배열 반환
# - 적용 - apply(): 적용함수의 반환값에 제한 없음
# ### 3.1 transform() 함수
# In[ ]:
df
# In[ ]:
k1_means = df.groupby('key1').mean().add_prefix('mean_')
k1_means
# In[ ]:
# groupby agg() 와 merge()로 transform() 구현
pd.merge(df, k1_means, left_on='key1', right_index=True)
# In[ ]:
people
# In[ ]:
key = ['one', 'two', 'one', 'two', 'one']
# In[ ]:
# agg()
people.groupby(key).mean()
# In[ ]:
# transform()
people.groupby(key).transform(np.mean)
# In[ ]:
# transform(): 각 값에서 평균 빼기
def demean(arr):
return arr - arr.mean()
demeaned = people.groupby(key).transform(demean)
demeaned
# In[ ]:
demeaned.groupby(key).mean()
# ### 3.2 apply() 함수: 분리-적용-병합
# In[ ]:
def top(df, n=5, column='tip_pct'):
return df.sort_values(by=column)[-n:]
# In[ ]:
top(tips, n=6)
# In[ ]:
# 사용자 함수 적용
tips.groupby('smoker').apply(top)
# In[ ]:
# 적용 함수에 인자 입력
tips.groupby(['smoker', 'day']).apply(top, n=1, column='total_bill')
# #### 그룹 색인 생략
# In[ ]:
tips.groupby('smoker', group_keys=False).apply(top)
# ### 3.3 변위치 분석과 버킷 분석
# In[ ]:
frame = pd.DataFrame({'data1': np.random.randn(1000),
'data2': np.random.randn(1000)})
quartiles = pd.cut(frame.data1, 4)
quartiles[:10]
# In[ ]:
def get_stats(group):
return {'min': group.min(), 'max': group.max(),
'count': group.count(), 'mean': group.mean()}
# In[ ]:
grouped = frame.data2.groupby(quartiles)
grouped.apply(get_stats).unstack()
# In[ ]:
# Return quantile numbers
grouping = pd.qcut(frame.data1, 10, labels=False)
grouped = frame.data2.groupby(grouping)
grouped.apply(get_stats).unstack()
# ### 3.4 예제: 그룹별 결측치 처리
# In[ ]:
s = pd.Series(np.random.randn(6))
s[::2] = np.nan
s
# In[ ]:
# 평균으로 결측치 채우기
s.fillna(s.mean())
# In[ ]:
states = ['Ohio', 'New York', 'Vermont', 'Florida',
'Oregon', 'Nevada', 'California', 'Idaho']
data = pd.Series(np.random.randn(8), index=states)
data
# In[ ]:
data[['Vermont', 'Nevada', 'Idaho']] = np.nan
data
# In[ ]:
group_key = ['East'] * 4 + ['West'] * 4
group_key
# In[ ]:
data.groupby(group_key).mean()
# In[ ]:
# 그룹별 평균값으로 결측치 채우기
fill_mean = lambda g: g.fillna(g.mean())
data.groupby(group_key).apply(fill_mean)
# In[ ]:
# mapping 값으로 결측치 채우기
fill_values = {'East': 0.5, 'West': -1}
fill_func = lambda g: g.fillna(fill_values[g.name])
data.groupby(group_key).apply(fill_func)
# ---
# # 4. 피벗 데이블, 교차 일람표(Cross Table)
# ### 4.1 피벗 데이블
# In[ ]:
tips.head()
# In[ ]:
# Default: 평균
tips.pivot_table(index=['day', 'smoker'])
#tips.pivot_table(index=['day', 'smoker'], aggfunc='mean')
# In[ ]:
tips.pivot_table(['tip_pct', 'size'], index=['time', 'day'],
columns='smoker')
# In[ ]:
tips.pivot_table(['tip_pct', 'size'], index=['time', 'day'],
columns='smoker', margins=True)
# In[ ]:
tips.pivot_table('tip_pct', index=['time', 'smoker'], columns='day',
aggfunc=len, margins=True)
# In[ ]:
# 결측치 0으로 채우기
tips.pivot_table('tip_pct', index=['time', 'size', 'smoker'],
columns='day', aggfunc='mean', fill_value=0)
# ### 4.2 교차 일람표(Cross Table)
# In[ ]:
from io import StringIO
data = """Sample Nationality Handedness
1 USA Right-handed
2 Japan Left-handed
3 USA Right-handed
4 Japan Right-handed
5 Japan Left-handed
6 Japan Right-handed
7 USA Right-handed
8 USA Left-handed
9 Japan Right-handed
10 USA Right-handed"""
data = pd.read_table(StringIO(data), sep='\s+')
# In[ ]:
data
# In[ ]:
pd.crosstab(data.Nationality, data.Handedness, margins=True)
# In[ ]:
pd.crosstab([tips.time, tips.day], tips.smoker, margins=True)
# ---
# In[ ]:
# end of file
# In[ ]:
반응형
LIST
'Programming' 카테고리의 다른 글
[Python][Library] 3. matplotlib - 1. 시각화 (0) | 2022.01.02 |
---|---|
[Python][Library] 2. Pandas - 5. 시계열 (0) | 2022.01.02 |
[Python][Library] 2 Pandas - 3 데이터 처리 (0) | 2022.01.02 |
[Python][Library] 2 Pandas - 2. 파일 입출력 (0) | 2022.01.02 |
[Python][Library] 2 Pandas - 1. 자료구조 (0) | 2022.01.02 |