Task 3 分组
一、分组操作过程
-
split :基于规则将数据拆成若干组。
-
apply :对每组独立使用函数。
-
combine:将每组的结果组合成一类数据结构。
apply过程:
aggregation :整合,分组计算统计量
transformation :变换,分组对每个单元数据进行操作
filtration : 过滤
二、groupby函数
(b)分组对象的head和first
返回每个组的前几行
三、聚合、变换、过滤
- 聚合 aggregation
聚合:将一堆数,变成一个标量。如mean/sum/size/count/std/var/sem/describe/first/last/nth/min/max
agg函数传入数据,是分组、逐列输入的
- 过滤 filteration
filter用来筛选组,结果是组的全体,为此需要传入bool标量
- 变换 transformation
四、apply函数 整合
apply函数的灵活性
用apply同时统计多个指标
问题
【问题一】 什么是fillna的前向/后向填充,如何实现?
前向填充:数据缺失部分参考前面的填充。后向填充反之。
df2 = pd.DataFrame(np.arange(12).reshape(3,4), columns=list('ABCD'))
df2['A'][1] , df2['C'][1] = np.nan, np.nan
print(df2.head())
print( df2.fillna(method='ffill') )
print('---')
print( df2.fillna(method='bfill') )
【问题二】 下面的代码实现了什么功能?请仿照设计一个它的groupby版本。
s = pd.Series ([0, 1, 1, 0, 1, 1, 1, 0])
s1 = s.cumsum()
result = s.mul(s1).diff().where(lambda x: x < 0).ffill().add(s1,fill_value =0)
display(result)
0 0.0
1 1.0
2 2.0
3 0.0
4 1.0
5 2.0
6 3.0
7 0.0
dtype: float64
【问题三】 如何计算组内0.25分位数与0.75分位数?要求显示在同一张表上。
data_t = pd.read_csv('data/table.csv', index_col='ID')
df3 = data_t[['Math','Class']]
# df3.groupby('Class')['Math'].agg(lambda x:x.quantile(0.25))
# df3.groupby('Class')['Math'].sort_index().apply(lambda x: pd.DataFrame(
# {'col1':x.quantile(0.25),
# 'col2':x.quantile(0.75) }))
# 错
df3.groupby('Class')['Math'].agg(col01=pd.NamedAgg(column='col1', aggfunc=(lambda x:x.quantile(0.25)) ),
col02=pd.NamedAgg(column='col2', aggfunc=(lambda x:x.quantile(0.75)))
)
【问题五】 整合、变换、过滤三者在输入输出和功能上有何异同?
- 整合::输入一个数组,输出一个数
- 变换::输入、输出的shape相同
- 过滤::输入n组数据,输出返回条件的组
#【练习一】:
现有一份关于diamonds的数据集,列分别记录了克拉数、颜色、开采深度、价格,请解决下列问题:
import pandas as pd
import numpy as np
data = pd.read_csv('data/Diamonds.csv')
data.head()
# (a) 在所有重量超过1克拉的钻石中,价格的极差是多少?
data[data['carat']>1]['price'].agg(lambda x:x.max()-x.min())
# :17561
# (b) 若以开采深度的0.2\0.4\0.6\0.8分位数为分组依据,
# 每一组中钻石颜色最多的是哪一种?该种颜色是组内平均而言单位重量最贵的吗?
bins = [0,data['depth'].quantile(0.2), data['depth'].quantile(0.4),data['depth'].quantile(0.6),data['depth'].quantile(0.8),data['depth'].max()]
cuts = pd.cut(data['depth'], bins=bins) #指定区间
data['cuts'] = cuts
result = data.set_index('cuts').sort_index().groupby('cuts')['color'].describe()
result
data['平均单位价格'] = data['price']/data['carat']
result['top'] == [i[1] for i in data.groupby(['cuts','color'])['平均单位价格'].mean().groupby(['cuts']).idxmax().values ]
# (c) 以重量分组(0-0.5,0.5-1,1-1.5,1.5-2,2+),按递增的深度为索引排序,求每组中连续的严格递增价格序列长度的最大值。
# (d) 请按颜色分组,分别计算价格关于克拉数的回归系数。(单变量的简单线性回归,并只使用Pandas和Numpy完成)
【练习二】:
有一份关于美国10年至17年的非法药物数据集,列分别记录了年份、州(5个)、县、药物类型、报告数量,请解决下列问题:
(a) 按照年份统计,哪个县的报告数量最多?这个县所属的州在当年也是报告数最多的吗?
(b) 从14年到15年,Heroin的数量增加最多的是哪一个州?它在这个州是所有药物中增幅最大的吗?若不是,请找出符合该条件的药物。
data2 = pd.read_csv('data/Drugs.csv')
data2.head()
df = data2
# 按照年份统计,哪个县的报告数量最多?这个县所属的州在当年也是报告数最多的吗
idx=pd.IndexSlice
for i in range(2010,2018):
county = (df.groupby(['COUNTY','YYYY']).sum().loc[idx[:,i],:].idxmax()[0][0])
state = df.query('COUNTY == "%s"'%county)['State'].iloc[0]
state_true = df.groupby(['State','YYYY']).sum().loc[idx[:,i],:].idxmax()[0][0]
if state==state_true:
print('在%d年,%s县的报告数最多,它所属的州%s也是报告数最多的'%(i,county,state))
else:
print('在%d年,%s县的报告数最多,但它所属的州%s不是报告数最多的,%s州报告数最多'%(i,county,state,state_true))
# 从14年到15年,Heroin的数量增加最多的是哪一个州?它在这个州是所有药物中增幅最大的吗?若不是,请找出符合该条件的药物。
df_b = df[(df['YYYY'].isin([2014,2015]))&(df['SubstanceName']=='Heroin')]
df_add = df_b.groupby(['YYYY','State']).sum()
print((df_add.loc[2015]-df_add.loc[2014]).idxmax())
df_b = df[(df['YYYY'].isin([2014,2015]))&(df['State']=='OH')]
df_add = df_b.groupby(['YYYY','SubstanceName']).sum()
print((df_add.loc[2015]-df_add.loc[2014]).idxmax()) #这里利用了索引对齐的特点
print((df_add.loc[2015]/df_add.loc[2014]).idxmax())
在2010年,PHILADELPHIA县的报告数最多,它所属的州PA也是报告数最多的
在2011年,PHILADELPHIA县的报告数最多,但它所属的州PA不是报告数最多的,OH州报告数最多
在2012年,PHILADELPHIA县的报告数最多,但它所属的州PA不是报告数最多的,OH州报告数最多
在2013年,PHILADELPHIA县的报告数最多,但它所属的州PA不是报告数最多的,OH州报告数最多
在2014年,PHILADELPHIA县的报告数最多,但它所属的州PA不是报告数最多的,OH州报告数最多
在2015年,PHILADELPHIA县的报告数最多,但它所属的州PA不是报告数最多的,OH州报告数最多
在2016年,HAMILTON县的报告数最多,它所属的州OH也是报告数最多的
在2017年,HAMILTON县的报告数最多,它所属的州OH也是报告数最多的
DrugReports OH
dtype: object
DrugReports Heroin
dtype: object
DrugReports Acetyl fentanyl
dtype: object