Joyful-Pandas:第3章 分组


本章思维导图

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述


本章问题与练习

  • 【练习一】 现有一份关于diamonds的数据集,列分别记录了克拉数、颜色、开采深度、价格,请解决下列问题:

(a)在所有重量超过1克拉的钻石中,价格的极差是多少?

df = pd.read_csv('data/Diamonds.csv')
df_r = df.query('carat>1')['price']
tp1 = df_r.max()-df_r.min()
print(tp1)

# 17561

(b)若以开采深度的0.2\0.4\0.6\0.8分位数为分组依据,每一组中钻石颜色最多的是哪一种?该种颜色是组内平均而言单位重量最贵的吗?

bins = df['depth'].quantile(np.linspace(0,1,6)).tolist()
cuts = pd.cut(df['depth'],bins=bins) #可选label添加自定义标签
df['cuts'] = cuts
print(df.head())

#   carat color	depth	price	cuts
# 0	0.23	E	61.5	326	(60.8, 61.6]
# 1	0.21	E	59.8	326	(43.0, 60.8]
# 2	0.23	E	56.9	327	(43.0, 60.8]
# 3	0.29	I	62.4	334	(62.1, 62.7]
# 4	0.31	J	63.3	335	(62.7, 79.0]

color_result = df.groupby('cuts')['color'].describe()
print(color_result)

#               count	unique	top	freq
# cuts				
# (43.0, 60.8]	11294	7	E	2259
# (60.8, 61.6]	11831	7	G	2593
# (61.6, 62.1]	10403	7	G	2247
# (62.1, 62.7]	10137	7	G	2193
# (62.7, 79.0]	10273	7	G	2000

# 前三个分位数区间不满足条件,后两个区间中数量最多的颜色的确是均重价格中最贵的
df['均重价格']=df['price']/df['carat']
color_result['top'] == [i[1] for i in df.groupby(['cuts','color'])['均重价格'].mean().groupby(['cuts']).idxmax().values

# cuts
# (43.0, 60.8]    False
# (60.8, 61.6]    False
# (61.6, 62.1]    False
# (62.1, 62.7]     True
# (62.7, 79.0]     True
# Name: top, dtype: bool

(c)以重量分组(0-0.5,0.5-1,1-1.5,1.5-2,2+),按递增的深度为索引排序,求每组中连续的严格递增价格序列长度的最大值。

df = df.drop(columns='均重价格')
cuts = pd.cut(df['carat'],bins=[0,0.5,1,1.5,2,np.inf]) #可选label添加自定义标签
df['cuts'] = cuts
print(df.head())

#   carat	color	depth	price	cuts
# 0	0.23	E	61.5	326	(0.0, 0.5]
# 1	0.21	E	59.8	326	(0.0, 0.5]
# 2	0.23	E	56.9	327	(0.0, 0.5]
# 3	0.29	I	62.4	334	(0.0, 0.5]
# 4	0.31	J	63.3	335	(0.0, 0.5]

def f(nums):
    if not nums:        
        return 0
    res = 1                            
    cur_len = 1                        
    for i in range(1, len(nums)):      
        if nums[i-1] < nums[i]:        
            cur_len += 1                
            res = max(cur_len, res)     
        else:                       
            cur_len = 1                 
    return res
    
for name,group in df.groupby('cuts'):
    group = group.sort_values(by='depth')
    s = group['price']
    print(name,f(s.tolist()))

# (0.0, 0.5] 8
# (0.5, 1.0] 8
# (1.0, 1.5] 7
# (1.5, 2.0] 11
# (2.0, inf] 7

(d)请按颜色分组,分别计算价格关于克拉数的回归系数。(单变量的简单线性回归,并只使用Pandas和Numpy完成)

for name,group in df[['carat','price','color']].groupby('color'):
    L1 = np.array([np.ones(group.shape[0]),group['carat']]).reshape(2,group.shape[0])
    L2 = group['price']
    result = (np.linalg.inv(L1.dot(L1.T)).dot(L1)).dot(L2).reshape(2,1)
    print('当颜色为%s时,截距项为:%f,回归系数为:%f'%(name,result[0],result[1]))

# 当颜色为D时,截距项为:-2361.017152,回归系数为:8408.353126
# 当颜色为E时,截距项为:-2381.049600,回归系数为:8296.212783
# 当颜色为F时,截距项为:-2665.806191,回归系数为:8676.658344
# 当颜色为G时,截距项为:-2575.527643,回归系数为:8525.345779
# 当颜色为H时,截距项为:-2460.418046,回归系数为:7619.098320
# 当颜色为I时,截距项为:-2878.150356,回归系数为:7761.041169
# 当颜色为J时,截距项为:-2920.603337,回归系数为:7094.192092
  • 【练习二】 有一份关于美国10年至17年的非法药物数据集,列分别记录了年份、州(5个)、县、药物类型、报告数量,请解决下列问题:

(a)按照年份统计,哪个县的报告数量最多?这个县所属的州在当年也是报告数最多的吗?

df = pd.read_csv('data/Drugs.csv')
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))

# 在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也是报告数最多的

(b)从14年到15年,Heroin的数量增加最多的是哪一个州?它在这个州是所有药物中增幅最大的吗?若不是,请找出符合该条件的药物。

df_b = df[(df['YYYY'].isin([2014,2015]))&(df['SubstanceName']=='Heroin')]
df_add = df_b.groupby(['YYYY','State']).sum()
(df_add.loc[2015]-df_add.loc[2014]).idxmax()

# DrugReports    OH
# dtype: object

df_b = df[(df['YYYY'].isin([2014,2015]))&(df['State']=='OH')]
df_add = df_b.groupby(['YYYY','SubstanceName']).sum()
display((df_add.loc[2015]-df_add.loc[2014]).idxmax()) #这里利用了索引对齐的特点
display((df_add.loc[2015]/df_add.loc[2014]).idxmax())

# DrugReports    Heroin
# dtype: object
# DrugReports    Acetyl fentanyl
# dtype: object

补充

在这里插入图片描述

df.index # 它的index第一个就是(‘A’,‘a’)

它是两层level,元组的第一个位置代表level0的元素,第二个位置代表level1的元素
df_s.index.get_level_values(0) # 返回level0的索引元素
df_s.index.get_level_values(1) # 返回level1的索引元素


参考:joyful-pandas:第3章 分组

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值