在机器学习中,经常会对数据进⾏分箱处理操作,即将⼀段连续的值切分为若⼲段,每⼀段的值当成⼀个分类。这个将连续值转换成离散值的过程,就是分箱处理。
例如:把年龄划分为18岁以下、18-30岁、30-45岁、45-60岁、60岁以上等5个标签(类别)。Pandas 包中的 cut 和 qcut 都可以实现分箱操作,区别在于:
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 pdimport 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] 2dtype: 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 npimport 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] 3dtype: 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 pdimport 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'])
参考链接:参考链接:参考链接:参考链接:
因篇幅问题不能全部显示,请点此查看更多更全内容