相信很多进行数据处理工作的小伙伴都遇到过这种需求,比如已经有了各个销售员的销售业绩,现在需要给各个销售业绩进行一个分档,诸如未完成任务,完成任务,超额完成任务等。要完成分档需要先对销售业绩的数值进行判断,然后再根据判断的结果进行一个分类,那么大家都是怎样进行分类的呢?
实际上,上述需求是要对连续型的数值进行分箱操作,实现的方法有N种,但是效率有高有低,这里我们介绍一种效率比较高而且也容易理解的方法,运用DataFrame种的一个函数,叫做pd.cut()实现分箱操作。
pd.cut()参数介绍
先来看一下这个函数都包含有哪些参数,主要参数的含义与作用都是什么?
pd.cut( x, bins, right=True, labels=None, retbins=False, precision=3, include_lowest=False, duplicates=‘raise’, )
x : 一维数组(对应前边例子中提到的销售业绩)
bins :整数,标量序列或者间隔索引,是进行分组的依据,
如果填入整数n,则表示将x中的数值分成等宽的n份(即每一组内的最大值与最小值之差约相等);
如果是标量序列,序列中的数值表示用来分档的分界值
如果是间隔索引,“ bins”的间隔索引必须不重叠
right :布尔值,默认为True表示包含最右侧的数值
当“ right = True”(默认值)时,则“ bins”=[1、2、3、4]表示(1,2],(2,3],(3,4]
当bins是一个间隔索引时,该参数被忽略。
labels : 数组或布尔值,可选.指定分箱的标签
如果是数组,长度要与分箱个数一致,比如“ bins”=[1、2、3、4]表示(1,2],(2,3],(3,4]一共3个区间,则labels的长度也就是标签的个数也要是3
如果为False,则仅返回分箱的整数指示符,即x中的数据在第几个箱子里
当bins是间隔索引时,将忽略此参数
retbins: 是否显示分箱的分界值。默认为False,当bins取整数时可以设置retbins=True以显示分界值,得到划分后的区间
precision:整数,默认3,存储和显示分箱标签的精度。
include_lowest:布尔值,表示区间的左边是开还是闭,默认为false,也就是不包含区间左边。
duplicates:如果分箱临界值不唯一,则引发ValueError或丢弃非唯一
ok,所有参数的含义与作用就是这些了,纯文字解释怎么都不如代码跑一遍来的直观,我们在代码中实现一下再结合上述文字解释就很容易理解了。而且并不是所有参数都是常用的,有些参数很少用到!
示例:
pd.cut(df_f.积分,bins=3,labels=[“低”,“中”,“高”]) #分成3箱并指定标签
可以通过参数进行设置显示分界值
pd.cut(df_f.积分,3,labels=[“低”,“中”,“高”],retbins=True) #retbins=True显示分界值
多了一个 array([13.953 , 29.66666667, 45.33333333, 61. ]),这就是分箱的分界值
bins取标量序列
pd.cut(df_f.积分,[0,30,40,70],labels=[“低”,“中”,“高”]) #默认right = True
指定分箱时候的分界点,即030,3040,4070一共三个箱体,有默认的right = True,即分箱的时候,30包含在030的箱体中,40包含在3040的箱体中,70包含在4070的箱体中
如果需要将分箱的结果展示在原数据框中,直接赋值一列进去就可以了:
df_f.loc[:,“积分等级”]=pd.cut(df_f.积分,[0,30,40,70],labels=[“低”,“中”,“高”],right=False)
案例1
import pandas as pd
import numpy as np
a = [30, 60, 80, 85, 100]
bin = [0, 60, 80, 90, 100]
rank = pd.cut(a, bin)
print(rank)
print(pd.value_counts(rank))
type(rank)
结果输出
[(0, 60], (0, 60], (60, 80], (80, 90], (90, 100]]
Categories (4, interval[int64]): [(0, 60] < (60, 80] < (80, 90] < (90, 100]]
(0, 60] 2
(90, 100] 1
(80, 90] 1
(60, 80] 1
dtype: int64
pandas.core.arrays.categorical.Categorical
案例2
import pandas as pd
import numpy as np
a = pd.Series([30, 60, 80, 85, 100])
bin = [0, 60, 80, 90, 100]
rank = pd.cut(a, bin, label=['不及格', '及格', '良好', '优秀'])
rank
type(rank)
# 结果输出============================================
0 不及格
1 不及格
2 及格
3 良好
4 优秀
dtype: category
Categories (4, object): [不及格 < 及格 < 良好 < 优秀]
pandas.core.series.Series
'''
函数二
pandas.qcut(x, q, labels=None, retbins=False, precision=3, duplicates=’raise’)
x: 要分组的数据
q: 整数,按分位数划分,会尽量保持落入每个区间的样本数量相同 分位数组成的数组
案例1
import pandas as pd
import numpy as np
a = pd.Series([30, 60, 80, 85, 100])
rank1 = pd.qcut(a, 3)
rank2 = pd.qcut(a, [0, 0.2, 0.3,1])
rank1
# 输出结果===================================
0 (29.999, 66.667]
1 (29.999, 66.667]
2 (66.667, 83.333]
3 (83.333, 100.0]
4 (83.333, 100.0]
dtype: category
Categories (3, interval[float64]): [(29.999, 66.667] < (66.667, 83.333] < (83.333, 100.0]]
0 (29.999, 54.0]
1 (54.0, 64.0]
2 (64.0, 100.0]
3 (64.0, 100.0]
4 (64.0, 100.0]
dtype: category
Categories (3, interval[float64]): [(29.999, 54.0] < (54.0, 64.0] < (64.0, 100.0]]
总结:
cut在划分区间时,按照绝对值
qcut在划分区间时,使用分位数