Python实现连续数据的离散化处理主要基于两个函数,pandas.cut和pandas.qcut,今天主要介绍这两个函数。
我们先回忆一下,连续数据离散化方法中无监督学习方法主要有两种:
pandas.cut()是按指定分界点对连续数据进行分箱处理。
pd.cut(x, bins, right=True, labels=None, retbins=False, precision=3, include_lowest=False)
x:需要离散化的数组、Series、DataFrame对象
bins:,分组数据,输入整数、序列尺度、或间隔索引,如果bins是一个整数,它定义了x宽度范围内的等宽面元数量,但是在这种情况下,x的范围在每个边上被延长1%,以保证包括x的最小值或最大值。如果bin是序列,它定义了允许非均匀bin宽度的bin边缘。在这种情况下没有x的范围的扩展。
right:right=True表示分组右边闭合,right=False表示分组左边闭合
labels:表示分组的自定义标签,必须与结果箱相同长度。如果FALSE,只返回整数指标面元。
retbins:布尔值,是否返回面元,retbins为True还返回用浮点数填充的N维数组
precision:整数。返回面元的小数点几位
include_lowest:布尔值,第一个区间的左端点是否包含
下面我们用代码了解其主要做作用:
#导包
import numpy as np
import pandas as pd
# 有一组人员年龄数据,希望将这些数据划分为"18到25","26到35","36到60","60以上"几个面元
ages = [20, 22, 25, 27, 21, 23, 37, 31, 61, 45, 41, 32]
bins = [18, 25, 35, 60, 100] ]# 指定箱子的分界点
pandas.cut函数:
cut_1= pd.cut(ages,bins)
cut_1
cut_1输出结果:返回的是一个特殊的Categorical对象–一组表示面元名称的字符串
[(18, 25], (18, 25], (18, 25], (25, 35], (18, 25], …, (25, 35], (60, 100], (35, 60],
(35, 60], (25, 35]]
Length: 12
Categories (4, interval[int64]): [(18, 25] < (25, 35] < (35, 60] < (60, 100]]
#labels参数为False时,返回结果中用不同的整数作为箱子的指示符
cats2 = pd.cut(ages, bins,labels=False)
cats2
cats2结果:
array([0, 0, 0, 1, 0, 0, 2, 1, 3, 2, 2, 1], dtype=int64)
对不同箱子中的数进行计数
pd.value_counts(cats1)
输出结果:
(18, 25] 5
(35, 60] 3
(25, 35] 3
(60, 100] 1
dtype: int64
指定分箱区间是左闭右开
pd.cut(ages, [18, 26, 36, 61, 100], right=False)
改变区间开闭结果:
[[18, 26), [18, 26), [18, 26), [26, 36), [18, 26), …, [26, 36), [61, 100), [36, 61),
[36, 61), [26, 36)]
Length: 12
Categories (4, interval[int64]): [[18, 26) < [26, 36) < [36, 61) < [61, 100)]
可以将想要指定给不同箱子的标签传递给labels参数
group_names = ['Youth', 'YoungAdult', 'MiddleAged', 'Senior']
cuts3 = pd.cut(ages, bins, labels=group_names)
cuts3
cats3结果:
[Youth, Youth, Youth, YoungAdult, Youth, …, YoungAdult, Senior, MiddleAged,
MiddleAged, YoungAdult]
Length: 12
Categories (4, object): [Youth < YoungAdult < MiddleAged < Senior]
pandas.qcut()是按照分位数对样本进行划分的,这样划分的结果是的每个区间的大小基本相同,但不一定完全相同。例如把a列分成4等份,就是按照四分位数划分的。
andas.qcut(x, q, labels=None, retbins=False, precision=3, duplicates=’raise’)
下面我们用代码了解其主要做作用:
qcats1 = pd.qcut(ages,q=4) # 参数q指定所分箱子的数量
qcats1
qcat_1 的结果
[(19.999, 22.75], (19.999, 22.75], (22.75, 29.0], (22.75, 29.0], (19.999, 22.75], …,
(29.0, 38.0], (38.0, 61.0], (38.0, 61.0], (38.0, 61.0], (29.0, 38.0]]
Length: 12
Categories (4, interval[float64]): [(19.999, 22.75] < (22.75, 29.0] < (29.0, 38.0] <
(38.0, 61.0]]
qcats1.value_counts() # 从输出结果可以看到每个箱子中的数据量时相同的
输出结果
(19.999, 22.75] 3
(22.75, 29.0] 3
(29.0, 38.0] 3
(38.0, 61.0] 3
dtype: int64
两者功能相似,都是将一个Series切割成若干个分组;
从上述的函数的结果来看,两者之间存在差异,
qcut 是等频切割,即基本保证每个组里的元素个数是相等的,
cut是按值切割,即根据数据值的大小范围等分成n组,落入这个范围的分别进入到该组。