10_分组与分箱

分组与分箱

学习目标

  • 知道Pandas分组聚合的使用方法
  • 知道Pandas数据离散化分箱操作的使用方法

1 分组对象DataFrameGroupBy

1.1 df.groupby分组函数返回分组对象

  • 导入pandas包, 加载链家租房数据集

    import pandas as pd
    
    # 加载数据集, 查看前5条数据
    df = pd.read_csv('../data/LJdata.csv')
    print(df.head())
    
    # 输出结果如下
             区域          地址    户型  面积  价格  朝向    更新时间  看房人数
    0    燕莎租房        新源街  2150  58002017.07.21        26
    1    望京租房      澳洲康都  2179  78002017.07.23        33
    2  广安门租房      远见名苑  2186  80002017.07.20        34
    3  天通苑租房  天通苑北一区  21103  5300  东南  2017.07.25        30
    4  团结湖租房    团结湖北口  2163  64002017.07.26        30
    
  • 基于一列进行分组

    # 基于区域分组
    gs = df.groupby(by=['区域'])
    print(gs)
    # 获取每组的地址列
    print(gs['地址'])
    
    # 输出结果如下
    <pandas.core.groupby.generic.DataFrameGroupBy object at 0x7fb54301bb50>
    <pandas.core.groupby.generic.SeriesGroupBy object at 0x7fb55753ec10>
    
  • 基于多列进行分组

    # 基于不同区域, 不同户型分组
    gs = df.groupby(by=['区域', '户型'])
    print(gs)
    
    # 输出结果如下
    <pandas.core.groupby.generic.DataFrameGroupBy object at 0x7fb956bdac10>
    
  • 返回的分组对象可以直接使用,或选择一列做聚合、转换、过滤操作;比如要计算不同区域、不同户型的平均租金

    res = df.groupby(by=['区域', '户型'])['价格'].mean()
    print(res)
    
    # 输出结果如下
    区域          户型
    CBD租房       1110700.000000
                  2114250.000000
                  2216000.000000
                  3121333.333333
                  4218000.000000
                                ...     
    鼓楼大街租房  101900.000000
                  111800.000000
                  213800.000000
                  224000.000000
                  314544.444444
    

1.2 取出每组第一条或最后一条数据

gs = df.groupby(by=['区域', '户型'])
# 获取每组第一条数据
print(gs.first())
# 获取每组最后一条数据
print(gs.last())

# 输出结果如下
                             地址  面积   价格       朝向    更新时间  看房人数
区域         户型                                                              
CBD租房      11厅  和乔丽致公寓    61  120002017.07.27         2
             21厅  金地国际花园   124  190002017.07.18        16
             22厅      盛世嘉园   161  160002017.07.27         1
             31厅    SOHO现代城   143  15000         西  2017.07.14        31
             42厅       阳光100   173  18000  东南 东北  2017.07.14         3
...                           ...   ...    ...        ...         ...       ...
鼓楼大街租房 10厅    北环里小区    37   19002017.07.21         7
             11厅    北环里小区    41   18002017.07.23         9
             21厅        邑上苑    88   4000      南 北  2017.07.23         0
             22厅    金隅万科城    89   4000       东南  2017.07.25        19
             31厅    金隅万科城    88   4800      南 北  2017.07.26        31

[793 rows x 6 columns]
                             地址  面积   价格       朝向    更新时间  看房人数
区域         户型                                                              
CBD租房      11厅  和乔丽致公寓    61  120002017.07.14         9
             21厅   建国路10061   60002017.07.20         2
             22厅      盛世嘉园   161  160002017.07.27         1
             31厅  金地国际花园   197  27000    西南 北  2017.07.15         6
             42厅       阳光100   173  18000  东南 东北  2017.07.14         3
...                           ...   ...    ...        ...         ...       ...
鼓楼大街租房 10厅    北环里小区    37   19002017.07.21         7
             11厅    北环里小区    41   18002017.07.23         9
             21厅    金隅万科城    85   40002017.07.26         0
             22厅    金隅万科城    89   4000       东南  2017.07.25        19
             31厅          蔚府   108   5500      南 北  2017.07.23         1

[793 rows x 6 columns]

1.3 获取分组后每组的名称

print(gs.grouper.result_index)

# 输出结果如下
MultiIndex([(  'CBD租房', '1室1厅'),
            (  'CBD租房', '2室1厅'),
            (  'CBD租房', '2室2厅'),
            (  'CBD租房', '3室1厅'),
            (  'CBD租房', '4室2厅'),
            (  '七里庄租房', '1室0厅'),
            (  '七里庄租房', '1室1厅'),
            (  '七里庄租房', '2室1厅'),
            (  '七里庄租房', '3室1厅'),
            (  '七里庄租房', '3室2厅'),
            ...
            (  '黄村北租房', '3室2厅'),
            (  '黄村北租房', '4室2厅'),
            ('黄村火车站租房', '2室1厅'),
            ('黄村火车站租房', '3室1厅'),
            ('黄村火车站租房', '3室2厅'),
            ( '鼓楼大街租房', '1室0厅'),
            ( '鼓楼大街租房', '1室1厅'),
            ( '鼓楼大街租房', '2室1厅'),
            ( '鼓楼大街租房', '2室2厅'),
            ( '鼓楼大街租房', '3室1厅')],
           names=['区域', '户型'], length=793)

1.4 gs.get_group()按分组依据获取其中一组

print(gs.get_group(name=('CBD租房', '1室1厅')))

# 输出结果如下
         区域          地址    户型  面积   价格   朝向    更新时间  看房人数
624   CBD租房  和乔丽致公寓  1161  120002017.07.27         2
645   CBD租房  和乔丽致公寓  1161  120002017.07.27         2
1359  CBD租房  和乔丽致公寓  1161  11000     西  2017.07.15         3
1383  CBD租房  和乔丽致公寓  1161  11000     西  2017.07.15         3
2073  CBD租房      光辉南里  1155   6200  东 南  2017.07.21         9
2562  CBD租房  和乔丽致公寓  1161  120002017.07.14         9

2 分组聚合

2.1 分组后直接聚合

分组后直接进行聚合计算并返回df

df.groupby(by=[列名1, 列名2, ...]).聚合函数()

  • 按区域分组, 计算每组的各数值列的平均值

    res = df.groupby(['区域']).mean()
    print(res)
    
    # 输出结果如下
                          面积          价格   看房人数
    区域                                               
    CBD租房         113.375000  14700.000000   6.750000
    七里庄租房       82.941176   5617.647059  13.764706
    万寿路租房       63.875000   6575.000000  14.875000
    万柳租房        137.916667  18629.166667  16.541667
    三元桥租房      103.045455  12581.818182  12.590909
    ...                    ...           ...        ...
    鲁谷租房         80.684211   6381.578947  11.421053
    黄村中租房       84.000000   3775.000000   3.250000
    黄村北租房      104.684211   5631.578947  14.473684
    黄村火车站租房   77.666667   3166.666667   7.666667
    鼓楼大街租房     89.000000   3987.500000   6.937500
    
    [208 rows x 3 columns]
    

2.2 分组后指定单列或多列聚合

根据1列或多列的值进行分组后, 每一组都对指定列的值使用聚合函数(比如mean求平均值)进行计算

对一列聚合可以使用一个[], 返回series对象; 也可以使用两个[], 返回dataframe对象

对多列聚合建议使用两个[[]], 返回dataframe对象

df.groupby(['列名1', '列名2'])['指定列1'].聚合函数()
df.groupby(['列名1', '列名2'])[['指定列1', '指定列2', ...]].聚合函数()

  • 按区域分组, 计算每组价格的平均值

    # 返回series对象
    res = df.groupby(['区域'])['价格'].mean()
    print(res)
    # 返回dataframe对象
    res = df.groupby(['区域'])[['价格']].mean()
    print(res)
    
    # 输出结果如下
    区域
    CBD租房           14700.000000
    七里庄租房         5617.647059
    万寿路租房         6575.000000
    万柳租房          18629.166667
    三元桥租房        12581.818182
                          ...     
    鲁谷租房           6381.578947
    黄村中租房         3775.000000
    黄村北租房         5631.578947
    黄村火车站租房     3166.666667
    鼓楼大街租房       3987.500000
    Name: 价格, Length: 208, dtype: float64
                            价格
    区域                        
    CBD租房         14700.000000
    七里庄租房       5617.647059
    万寿路租房       6575.000000
    万柳租房        18629.166667
    三元桥租房      12581.818182
    ...                      ...
    鲁谷租房         6381.578947
    黄村中租房       3775.000000
    黄村北租房       5631.578947
    黄村火车站租房   3166.666667
    鼓楼大街租房     3987.500000
    
    [208 rows x 1 columns]
    
  • 按区域分组, 计算每组价格和看房人数的平均值

    res = df.groupby(['区域'])[['价格', '看房人数']].mean()
    print(res)
    
    # 输出结果如下
                            价格   看房人数
    区域                                   
    CBD租房         14700.000000   6.750000
    七里庄租房       5617.647059  13.764706
    万寿路租房       6575.000000  14.875000
    万柳租房        18629.166667  16.541667
    三元桥租房      12581.818182  12.590909
    ...                      ...        ...
    鲁谷租房         6381.578947  11.421053
    黄村中租房       3775.000000   3.250000
    黄村北租房       5631.578947  14.473684
    黄村火车站租房   3166.666667   7.666667
    鼓楼大街租房     3987.500000   6.937500
    
    [208 rows x 2 columns]
    

2.3 分组后使用多个聚合函数

同时使用多个内置聚合函数,全部放入一个Python列表, 然后把整个列表传入agg或aggregate函数中;返回以分组列作为索引,每一个聚合计算结果作为列的全新df

df.groupby(['列名1', '列名2'])[['指定列1', '指定列2']].agg(['max', 'min'])

max, min 为pandas内置的聚合函数名

  • 按区域分组, 计算每组价格和看房人数的平均值和总数

    res = df.groupby(['区域'])[['价格', '看房人数']].agg(['mean', 'sum'])
    print(res)
    
    # 输出结果如下
                            价格           看房人数     
                            mean     sum       mean  sum
    区域                                                
    CBD租房         14700.000000  235200   6.750000  108
    七里庄租房       5617.647059   95500  13.764706  234
    万寿路租房       6575.000000   52600  14.875000  119
    万柳租房        18629.166667  447100  16.541667  397
    三元桥租房      12581.818182  276800  12.590909  277
    ...                      ...     ...        ...  ...
    鲁谷租房         6381.578947  242500  11.421053  434
    黄村中租房       3775.000000   15100   3.250000   13
    黄村北租房       5631.578947  107000  14.473684  275
    黄村火车站租房   3166.666667    9500   7.666667   23
    鼓楼大街租房     3987.500000   63800   6.937500  111
    
    [208 rows x 4 columns]
    

2.4 分组后对多列分别使用不同的聚合函数

agg函数中可以传入字典,字典的key是df的列名,与key对应的value是pandas内置的聚合计算函数、其名称的字符串;返回以分组列作为索引,每一个聚合计算结果作为列的全新df

df.groupby(['列名1', '列名2']).agg({ '指定列1':'mean', '指定列2':'sum', '指定列3':'mean' })

  • 按区域分组, 计算每组价格的平均值和看房人数的总数

    res = df.groupby(['区域']).agg({'价格': 'mean', '看房人数': 'sum'})
    print(res)
    
    # 输出结果如下
                            价格  看房人数
    区域                                  
    CBD租房         14700.000000       108
    七里庄租房       5617.647059       234
    万寿路租房       6575.000000       119
    万柳租房        18629.166667       397
    三元桥租房      12581.818182       277
    ...                      ...       ...
    鲁谷租房         6381.578947       434
    黄村中租房       3775.000000        13
    黄村北租房       5631.578947       275
    黄村火车站租房   3166.666667        23
    鼓楼大街租房     3987.500000       111
    
    [208 rows x 2 columns]
    

2.5 分组后使用自定义聚合函数

分组之后指定列,对该列的值使用自定义的函数

def bar(s, args1, args2):
    '''自定义函数
    s,为传入的series对象
    args1,args2为自定义传参
    '''
    s_mean = s.sum() / s.size
    return s_mean + args1 + args2
# 调用自定义函数
df.groupby(['列名1', '列名2']).agg(bar, args1=xxx, args2=xxx)
df.groupby(['列名1', '列名2'])['指定列1', '指定列2'].agg(bar, args1=xxx, args2=xxx)
  • 按区域分组, 计算每组价格和看房人数的平均值

    # 定义自定义函数
    def func(s):
        # 参数s是分组之后指定的每一列
        s_mean = s.sum() / s.size
        return s_mean
    
    
    res = df.groupby('区域')[['价格', '看房人数']].agg(func)
    print(res)
    # 与下面的代码效果相同
    # df.groupby('区域')[['价格', '看房人数']].mean()
    
    # 输出结果如下
                            价格   看房人数
    区域                                   
    CBD租房         14700.000000   6.750000
    七里庄租房       5617.647059  13.764706
    万寿路租房       6575.000000  14.875000
    万柳租房        18629.166667  16.541667
    三元桥租房      12581.818182  12.590909
    ...                      ...        ...
    鲁谷租房         6381.578947  11.421053
    黄村中租房       3775.000000   3.250000
    黄村北租房       5631.578947  14.473684
    黄村火车站租房   3166.666667   7.666667
    鼓楼大街租房     3987.500000   6.937500
    
    [208 rows x 2 columns]
    

3 数据离散化(分箱)

  • pd.cut()函数用来把一组数据分割成离散的区间。比如有一组年龄数据,可以使用pandas.cut将价格数据分割成不同的价格段并打上标签。上述过程又叫做分箱。

    pd.cut(x=Seriers对象, bins=3, labels=['低', '中', '高'])
    
  • 离散化分箱函数的常用参数有:

    • x 指定离散化(分箱)依据的列,Seriers对象
    • bins 分为几组,int类型,也可以传入分组区间的列表
    • labels 每组的标签名称,按数值由小到大的顺序
    • right 默认True:左开右闭;False:左闭右开
    • include_lowest 默认False:不包含第一个分组的起始值;True:包含
  • 按价格金额大小分为3组,将每条数据都打上高中低的标签

    df2 = df.copy() # 复制数据集 
    # 分箱返回Seriers对象并复制给新的列
    df2['价格高中低'] = pd.cut(x=df2['价格'], bins=3, labels=['低', '中', '高'])
    # df2['价格高中低'] = pd.cut(x=df2['价格'], bins=[0,3000,8000,210000], labels=['低', '中', '高'])
    df2
    

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

总结

请对下面的内容 有印象、能找到、能理解、能看懂

  • 分组对象

    • gs = df.groupby(['列1', '列2']) 按照列1、列2的值对数据集进行分组,返回分组对象
    • gs.first() 返回每组的第一条数据
    • gs.last() 返回每组的最后一条数据
    • gs.grouper.result_index 获取全部组名
    • gs.get_group((组名)) 按照
  • 分组聚合

    • 分组后直接聚合

      df.groupby(['列名1', '列名2']).聚合函数()
      
    • 分组后指定单列或多列聚合

      df.groupby(['列名1', '列名2'])['指定列'].聚合函数()
      
    • 分组后使用多个聚合函数

      df.groupby(['列名1', '列名2'])[['指定列1', '指定列2']].agg(['max', 'min'])
      
    • 分组后对多列分别使用不同的聚合函数

      df.groupby(['列名1', '列名2']).agg({
          '指定列1':'mean', 
          '指定列2':'sum', 
          '指定列3':'mean'
      })
      
    • 分组后使用自定义聚合函数

      def foo(s):
          # 参数s 是分组之后指定的每一列
          s_mean = s.sum() / s.size
          return s_mean
      df.groupby(['列名1', '列名2'])[['指定列1', '指定列2']].agg(foo)
      
  • 数据离散化(分箱)用来把一组数据分割成若干个离散的区间。比如有一组年龄数据,可以使用pandas.cut将年龄数据分割成不同的年龄段并打上标签。上述过程又叫做分箱。

    • 参数x 指定离散化(分箱)依据的列,Seriers对象

    • 参数bins 分为几组,int类型,也可以传入分组区间的列表

    • 参数labels 每组的标签名称,按数值由小到大的顺序

    • 参数right 默认True:左开右闭;False:左闭右开
      ‘指定列3’:‘mean’
      })

      
      
    • 分组后使用自定义聚合函数

      def foo(s):
          # 参数s 是分组之后指定的每一列
          s_mean = s.sum() / s.size
          return s_mean
      df.groupby(['列名1', '列名2'])[['指定列1', '指定列2']].agg(foo)
      
  • 数据离散化(分箱)用来把一组数据分割成若干个离散的区间。比如有一组年龄数据,可以使用pandas.cut将年龄数据分割成不同的年龄段并打上标签。上述过程又叫做分箱。

    • 参数x 指定离散化(分箱)依据的列,Seriers对象
    • 参数bins 分为几组,int类型,也可以传入分组区间的列表
    • 参数labels 每组的标签名称,按数值由小到大的顺序
    • 参数right 默认True:左开右闭;False:左闭右开
    • 参数include_lowest 默认False:不包含第一个分组的起始值;True:包含
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值