Pandas 统计分析基础 笔记4 任务4.4 使用分组聚合进行组内计算

pandas_任务4.4 使用分组聚合进行组内计算

!
!!
!!!可以点击下面连接
ipynb格式浏览

4.4.1 使用groupby方法拆分数据

代码 4-51 对菜品订单详情表依据订单编号分组

import pandas as pd
import numpy as np
from sqlalchemy import create_engine
engine = create_engine('mysql+pymysql://root:123456@localhost:3306/zuoye')
detail = pd.read_sql_table('meal_order_detail1',con = engine)
detailGroup = detail[['order_id','counts',
      'amounts']].groupby(by = 'order_id')
print('分组后的订单详情表为:',detailGroup)
分组后的订单详情表为: <pandas.core.groupby.generic.DataFrameGroupBy object at 0x000002547B8C0DC8>


D:\Study\anaconda\lib\site-packages\pymysql\cursors.py:170: Warning: (1366, "Incorrect string value: '\\xD6\\xD0\\xB9\\xFA\\xB1\\xEA...' for column 'VARIABLE_VALUE' at row 1")
  result = self._query(query)

代码 4-52 GroupBy 类求均值,标准差,中位数

print('订单详情表分组后前5组每组的均值为:\n', 
      detailGroup.mean().head())

print('订单详情表分组后前5组每组的标准差为:\n', 
      detailGroup.std().head())

print('订单详情表分组后前5组每组的大小为:','\n', 
      detailGroup.size().head())
订单详情表分组后前5组每组的均值为:
           counts  amounts
order_id                 
1002      1.0000   32.000
1003      1.2500   30.125
1004      1.0625   43.875
1008      1.0000   63.000
1011      1.0000   57.700
订单详情表分组后前5组每组的标准差为:
            counts    amounts
order_id                    
1002      0.00000  16.000000
1003      0.46291  21.383822
1004      0.25000  31.195886
1008      0.00000  64.880660
1011      0.00000  50.077828
订单详情表分组后前5组每组的大小为: 
 order_id
1002     7
1003     8
1004    16
1008     5
1011    10
dtype: int64

代码 4-53 agg和aggregate函数的参数及其说明

print('订单详情表的菜品销量与售价的和与均值为:\n',
      detail[['counts','amounts']].agg([np.sum,np.mean]))
订单详情表的菜品销量与售价的和与均值为:
            counts        amounts
sum   3088.000000  125992.000000
mean     1.111191      45.337172
订单详情表的菜品销量总和与售价的均值为:
 counts     3088.000000
amounts      45.337172
dtype: float64

代码 4-54 使用agg分别求字段的不同统计量

print('订单详情表的菜品销量总和与售价的均值为:\n',
      detail.agg({'counts':np.sum,'amounts':np.mean}))
订单详情表的菜品销量总和与售价的均值为:
 counts     3088.000000
amounts      45.337172
dtype: float64

代码 4-55 使用agg方法求不同字段的不同数目统计量

print('菜品订单详情表的菜品销量总和与售价的总和与均值为:\n',
      detail.agg({'counts':np.sum,'amounts':[np.mean,np.sum]}))
菜品订单详情表的菜品销量总和与售价的总和与均值为:
       counts        amounts
mean     NaN      45.337172
sum   3088.0  125992.000000

代码 4-56 在agg方法中使用自定义函数

##自定义函数求两倍的和
def DoubleSum(data):
    s = data.sum()*2
    return s
print('菜品订单详情表的菜品销量两倍总和为:','\n',
      detail.agg({'counts':DoubleSum},axis = 0))
菜品订单详情表的菜品销量两倍总和为: 
 counts    6176.0
dtype: float64

代码 4-57 agg方法中使用的自定义函数含NumPy中的函数

def DoubleSum1(data):
    s = np.sum(data)*2
    return s
print('订单详情表的菜品销量两倍总和为:\n',
      detail.agg({'counts':DoubleSum1},axis = 0).head())

print('订单详情表的菜品销量与售价的和的两倍为:\n',
      detail[['counts','amounts']].agg(DoubleSum1))
订单详情表的菜品销量两倍总和为:
    counts
0     2.0
1     2.0
2     2.0
3     2.0
4     2.0
订单详情表的菜品销量与售价的和的两倍为:
 counts       6176.0
amounts    251984.0
dtype: float64

代码 4-58 使用agg方法做简单的聚合

print('订单详情表分组后前3组每组的均值为:\n', 
      detailGroup.agg(np.mean).head(3))

print('订单详情表分组后前3组每组的标准差为:\n', 
      detailGroup.agg(np.std).head(3))
订单详情表分组后前3组每组的均值为:
           counts  amounts
order_id                 
1002      1.0000   32.000
1003      1.2500   30.125
1004      1.0625   43.875
订单详情表分组后前3组每组的标准差为:
            counts    amounts
order_id                    
1002      0.00000  16.000000
1003      0.46291  21.383822
1004      0.25000  31.195886

代码 4-59 使用ag方法对分组数据使用不同的聚合函数

print('订单详情分组前3组每组菜品总数和售价均值为:\n', 
      detailGroup.agg({'counts':np.sum,
            'amounts':np.mean}).head(3))
订单详情分组前3组每组菜品总数和售价均值为:
           counts  amounts
order_id                 
1002         7.0   32.000
1003        10.0   30.125
1004        17.0   43.875

4.4.3 使用apply方法聚合数据

代码 4-60 apply方法的基本用法

print('订单详情表的菜品销量与售价的均值为:\n',
      detail[['counts','amounts']].apply(np.mean))
订单详情表的菜品销量与售价的均值为:
 counts      1.111191
amounts    45.337172
dtype: float64

代码 4-61 使用apply方法进行聚合操作

print('订单详情表分组后前3组每组的均值为:','\n', detailGroup.apply(np.mean).head(3))
print('订单详情表分组后前3组每组的标准差为:','\n', detailGroup.apply(np.std).head(3))
订单详情表分组后前3组每组的均值为: 
               order_id  counts  amounts
order_id                               
1002      1.431572e+26  1.0000   32.000
1003      1.253875e+30  1.2500   30.125
1004      6.275628e+61  1.0625   43.875
订单详情表分组后前3组每组的标准差为: 
             counts    amounts
order_id                     
1002      0.000000  14.813122
1003      0.433013  20.002734
1004      0.242061  30.205287

使用transform 方法聚合数据

transform方法能够对整个DataFrame的所有元素进行操作。且transform方法只有一个参数“func”,表示对DataFrame操作的函数。

代码 4-62 使用transform方法将销量和售价翻倍

print('订单详情表的菜品销量与售价的两倍为:\n',
      detail[['counts','amounts']].transform(
            lambda x:x*2).head(4))
订单详情表的菜品销量与售价的两倍为:
    counts  amounts
0     2.0     98.0
1     2.0     96.0
2     2.0     60.0
3     2.0     50.0

代码 4-63 使用transform实现组内离差标准化

同时transform方法还能够对DataFrame分组后的对象GroupBy进行操作,可以实现组内离差标准化等操作。

 print('订单详情表分组后实现组内离差标准化后前五行为:\n', 
       detailGroup.transform(lambda x:(x-x.min())/(x.max()-x.min())).head())

若在计算离差标准化的时候结果中有NaN,这是由于根据离差标准化公式,最大值和最小值相同的情况下分母是0。而分母为0的数在Python中表示为NaN。
但是这里会报ZeroDivisionError: float division by zero的bug ,就是分母为0了,奇奇怪怪感觉,书上的运行得了
感谢@孤芳不自赏呀 的bug更正

4.4.5任务实现

代码 4-64 订单详情按照日期分组

detail = pd.read_sql_table('meal_order_detail1',con = engine)
detail['place_order_time'] = pd.to_datetime(detail['place_order_time'])
detail['date'] = [i.date() for i in detail['place_order_time']]
detailGroup = detail[['date','counts','amounts']].groupby(by='date')
print('订单详情表前5组每组的数目为:\n',detailGroup.size().head())
订单详情表前5组每组的数目为:
 date
2016-08-01    217
2016-08-02    138
2016-08-03    157
2016-08-04    144
2016-08-05    193
dtype: int64

代码 4-65 求分组后的订单详情表每日菜品销售的均价,中位数

dayMean = detailGroup.agg({'amounts':np.mean})
print('订单详情表前五组每日菜品均价为:\n',dayMean.head())

dayMedian = detailGroup.agg({'amounts':np.median})
print('订单详情表前五组每日菜品售价中位数为:\n',dayMedian.head())
订单详情表前五组每日菜品均价为:
               amounts
date                 
2016-08-01  43.161290
2016-08-02  44.384058
2016-08-03  43.885350
2016-08-04  52.423611
2016-08-05  44.927461
订单详情表前五组每日菜品售价中位数为:
             amounts
date               
2016-08-01     33.0
2016-08-02     35.0
2016-08-03     38.0
2016-08-04     39.0
2016-08-05     37.0

代码 4-66 求取订单详情表中单日菜品总销量

daySaleSum = detailGroup.apply(np.sum)['counts']
print('订单详情表前五组每日菜品售出数目为:\n',daySaleSum.head())

订单详情表前五组每日菜品售出数目为:
 date
2016-08-01    233.0
2016-08-02    151.0
2016-08-03    192.0
2016-08-04    169.0
2016-08-05    224.0
Name: counts, dtype: float64

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

数据闲逛人

谢谢大嘎喔~ 开心就好

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值