zoukankan      html  css  js  c++  java
  • Python学习笔记:pd.cut和pd.qcut实现数据分箱

    在机器学习中,经常会对数据进行分箱处理操作,即将一段连续的值切分为若干段,每一段的值当成一个分类。

    这个将连续值转换成离散值的过程,就是分箱处理。

    例如:把年龄划分为18岁以下、18-30岁、30-45岁、45-60岁、60岁以上等5个标签(类别)。

    Pandas 包中的 cutqcut 都可以实现分箱操作,区别在于:

    • cut:按照数值进行分割,等间隔
    • qcut:按照数据分布进行分割,等频率

    一、pd.cut函数

    1.使用语法

    pandas.cut(x,   # 被切分的数组
              bins, # 被切割后的区间(桶、箱)
              right=True, # 是否包含区间右部 默认为真
              labels=None, # 区间标签 与区间个数一致
              retbins=False, # 是否返回分割后的bins
              precision=3, # 小数点位
              include_lowest=False, # 左开区间
              duplicates='raise') # 是否允许重复区间
                       # raise:不允许  drop:允许
    

    2.实操

    • 构造测试集
    import pandas as pd
    import numpy as np
    
    ages = np.array([1,5,10,40,36,12,58,62,77,89,100,18,20,25,30,32])
    
    • 平分为5个区间
    # 平分为5个区间
    pd.cut(ages, 5)
    '''
    [(0.901, 20.8], (0.901, 20.8], (0.901, 20.8], (20.8, 40.6], (20.8, 40.6], ..., (0.901, 20.8], (0.901, 20.8], (20.8, 40.6], (20.8, 40.6], (20.8, 40.6]]
    Length: 16
    Categories (5, interval[float64]): [(0.901, 20.8] < (20.8, 40.6] < (40.6, 60.4] < (60.4, 80.2] <
                                        (80.2, 100.0]]
    '''
    
    pd.cut(ages, 5).value_counts()
    '''
    (0.901, 20.8]    6
    (20.8, 40.6]     5
    (40.6, 60.4]     1
    (60.4, 80.2]     2
    (80.2, 100.0]    2
    dtype: int64
    '''
    

    区间两边均有扩展,以包含最大值和最小值。

    • 平分并指定labels
    pd.cut(ages, 5, labels=['婴儿', '青年', '中年', '壮年', '老年'])
    '''
    ['婴儿', '婴儿', '婴儿', '青年', '青年', ..., '婴儿', '婴儿', '青年', '青年', '青年']
    Length: 16
    Categories (5, object): ['婴儿' < '青年' < '中年' < '壮年' < '老年']
    '''
    
    • 指定区间进行分割
    pd.cut(ages, 
           bins=[0,5,20,30,50,100],
           labels=['婴儿', '青年', '中年', '壮年', '老年'])
    '''
    ['婴儿', '婴儿', '青年', '壮年', '壮年', ..., '青年', '青年', '中年', '中年', '壮年']
    Length: 16
    Categories (5, object): ['婴儿' < '青年' < '中年' < '壮年' < '老年']
    '''
    
    • 返回分割后的bins(设置 retbins=True 即可)
    pd.cut(ages, 
           bins=[0,5,20,30,50,100],
           labels=['婴儿', '青年', '中年', '壮年', '老年'],
           retbins=True)
    '''
    (['婴儿', '婴儿', '青年', '壮年', '壮年', ..., '青年', '青年', '中年', '中年', '壮年']
     Length: 16
     Categories (5, object): ['婴儿' < '青年' < '中年' < '壮年' < '老年'],
     array([  0,   5,  20,  30,  50, 100]))
    '''
    
    • 只返回数据所属的bins(设置 labels=False 即可)
    pd.cut(ages,
           bins=[0,5,20,30,50,100],
           labels=False)
    # array([0, 0, 1, 3, 3, 1, 4, 4, 4, 4, 4, 1, 1, 2, 2, 3], dtype=int64)
    

    默认情况下,每个区间包括最大值,不包括最小值。

    最左边的值, 一般设置成最小值减去最大值的 0.1%。

    二、pd.qcut函数

    1.使用语法

    pd.qcut 实现按数据的数量进行分割,尽量保证每个分组里变量的个数相同。

    pd.qcut(
        x, # 数组
        q, # 组数 int
        labels=None, # 标签
        retbins: bool = False, # 是否返回边界值
        precision: int = 3, # 精度
        duplicates: str = "raise",
    )
    

    2.实操

    • 简单按个数分箱
    import numpy as np
    import pandas as pd
    
    factors = np.random.randn(9)
    pd.qcut(factors, 3)
    '''
    [(-0.272, 0.33], (0.33, 1.116], (0.33, 1.116], (0.33, 1.116], (-0.272, 0.33], (-1.101, -0.272], (-1.101, -0.272], (-0.272, 0.33], (-1.101, -0.272]]
    Categories (3, interval[float64]): [(-1.101, -0.272] < (-0.272, 0.33] < (0.33, 1.116]]
    '''
    pd.qcut(factors, 3).value_counts() # 均分
    '''
    (-1.101, -0.272]    3
    (-0.272, 0.33]      3
    (0.33, 1.116]       3
    dtype: int64
    '''
    
    
    • 添加labels标签
    pd.qcut(factors,
            3,
            labels=['a','b','c'])
    '''
    ['b', 'c', 'c', 'c', 'b', 'a', 'a', 'b', 'a']
    Categories (3, object): ['a' < 'b' < 'c']
    '''
    # 返回对应的分组下标
    pd.qcut(factors, 3, labels=False)
    # array([1, 2, 2, 2, 1, 0, 0, 1, 0], dtype=int64)
    
    
    • 返回bins值
    pd.qcut(factors, 3, retbins=True)
    '''
    ([(-0.272, 0.33], (0.33, 1.116], (0.33, 1.116], (0.33, 1.116], (-0.272, 0.33], (-1.101, -0.272], (-1.101, -0.272], (-0.272, 0.33], (-1.101, -0.272]]
     Categories (3, interval[float64]): [(-1.101, -0.272] < (-0.272, 0.33] < (0.33, 1.116]],
     array([-1.09994407, -0.27157169,  0.32984035,  1.11614022]))
    '''
    
    

    三、综合用法

    1.一个栗子

    import pandas as pd
    import numpy as np
    
    df = pd.DataFrame([x**2 for x in range(11)],
                      columns=['number'])
    
    # 按照数值由小到大 将数据分成4份
    df['cut_group'] = pd.cut(df['number'], 4)
    
    
    # 分成四组 并且让每组变量的数量相同
    df['qcut_group'] = pd.qcut(df['number'], 4)
    df['qcut_group'].value_counts()
    '''
    (-0.001, 6.5]    3
    (6.5, 25.0]      3
    (56.5, 100.0]    3
    (25.0, 56.5]     2
    '''
    
    

    3.日常工作使用

    cz_fee_cut = [min(df_copy.cz_fee)-10, 30, 50, 100, 150, 200, max(df_copy.cz_fee)+10]
    df_copy["cz_fee"] = pd.cut(df_copy['cz_fee'], 
                               bins=cz_fee_cut, 
                               right=False,
                               labels=['<30','[30,50)','[50,100)','[100,150)','[150,200)','≥200'])
    
    

    参考链接:pandas.cut

    参考链接:pandas.cut使用总结

    参考链接:Pandas —— qcut( )与cut( )的区别

    参考链接:pandas的cut,qcut函数的使用和区别

  • 相关阅读:
    HDU-4248 A Famous Stone Collector 组合数学 DP
    HDU
    暑期训练1 Gym
    暑期训练1 Gym-102623L Lottery Tickets 模拟 贪心构造
    暑期训练2 Gym
    poj-1011 sticks(搜索题)
    hdu-2553 N皇后问题(搜索题)
    poj-2236 wireless network(并查集)
    poj-1700 crossing river(贪心题)
    poj-3278 catch that cow(搜索题)
  • 原文地址:https://www.cnblogs.com/hider/p/15494513.html
Copyright © 2011-2022 走看看