对于一个一维的数值型数据,我们有时候想对其根据数值区间或者根据分位数进行分组,然后再做后续的分析,本文介绍pandas里的cut和qcut函数,实现这种快速分组操作。
cut函数,将一维序列中的数值打上区间标签,参数签名如下:
pandas.
cut
(
x
,
bins
,
right=True
,
labels=None
,
retbins=False
,
precision=3
,
include_lowest=False
,
duplicates='raise')
其中x必须是一维数据,区间标签中的区间由bins指定,可以为一个数值序列,比如[0,2,4,6],表示的区间为(0,2],(2,4],(4,6];也可以为整数,比如3,表示将x所蕴含的区间长度进行三等分,其中x所蕴含的区间长度就是最大值和最小值之差。比如:
In [2]: pd.cut([0,60,100,82,50],3)
Out[2]:
[(-0.1, 33.333], (33.333, 66.667], (66.667, 100.0], (66.667, 100.0], (33.333, 66.667]]
Categories (3, interval[float64]): [(-0.1, 33.333] < (33.333, 66.667] < (66.667, 100.0]]
这里将[0,60,100,82,50]进行三等分,区间长度为100-0=100,所以每个区间长度就是33.333。返回的是Categories类型。
这里默认等分后的区间是左开右闭的,也可以通过设置right参数为False,设置区间为左闭右开。
还可以注意到,当bins参数为整数时,对于开区间的一边,会默认延展千分之一的区间长度,以包含最小值(最大值),比如上面的例子中,最小区间的左边为-0.1,而不是0,这是因为pandas将区间向左边延展了千分之一(100*0.001=0.1),从而将x的最小值0包含进去。
对于区间的精度,可以通过precision参数控制,默认为3,那么上面例子中,区间的两边的值就会保留三位小数(比如(33.333,66.667]),你也可以设置为6,从而保留6位小数。
此外,如果想返回具体的切分点,即区间的边界点,可以将retbins设为True,这样就会返回一个二元组,其中第二个元素就是对应的Bins序列,如下所示:
In [6]: pd.cut([0,60,100,82,50],3,retbins=True)
Out[6]:
([(-0.1, 33.333], (33.333, 66.667], (66.667, 100.0], (66.667, 100.0], (33.333, 66.667]]
Categories (3, interval[float64]): [(-0.1, 33.333] < (33.333, 66.667] < (66.667, 100.0]],
array([ -0.1 , 33.33333333, 66.66666667, 100. ]))
如果你只是想要将数据按照相应的逻辑分好组就行,具体区别的区间标签不重要,那么你可以设置labels为False,那么该函数就会将不同的区间从小到大用整数标记,从0开始,如下所示,只会返回对应的整数标记。
In [7]: pd.cut([0,60,100,82,50],3,labels=False)
Out[7]: array([0, 1, 2, 2, 1], dtype=int64)
当然,如果你想要对不同的区间进行一些有意义的标记,则可以将有意义的标签序列传给labels参数,这里labels参数的序列长度必须要和区间的个数相等。如下所示。
In [8]: pd.cut([0,60,100,82,50],3,labels=['a','b','c'])
Out[8]:
[a, b, c, c, b]
Categories (3, object): [a < b < c]
最后,我们更常用的可能不是将数据根据区间长度进行等分,而是指定区间边界进行划分,这时可以将指定的边界序列传给bins参数实现,如下所示。
In [11]: pd.cut([0,60,100,82,50],bins=[0,2,30,50,80])
Out[11]:
[NaN, (50.0, 80.0], NaN, NaN, (30.0, 50.0]]
Categories (4, interval[int64]): [(0, 2] < (2, 30] < (30, 50] < (50, 80]]
可以看到,如果我们指定了bins序列的话,那么默认情况下,就会严格的按照bins中的数划分区间,不会自动将区间延展千分之一,当然,如果你此时设置include_lowest参数为True,那么会自动延展千分之一,不过这个参数只对最小值work,如果你设置right为False,那么即使设置include_lowest为True,并不会自动将最大区间的右边界延展千分之一。这里还需要注意的是,如果x中的值不在指定的bins区间中的话,对应位置的标签就会为nan。
还要注意,这里bins参数如果是指定的数值序列的话,那么其必须是严格递增的;但是如果bins中如果有重复数值的话,由于区间不允许为空,因此可以通过duplicates控制行为,如果为raise,则表示会抛出异常,如果为drop,则表示自动去重。
cut函数是直接通过数值区间对输入序列进行分组,如果我们想要对输入序列进行个数等分,或者按照不同组别的size大小对输入序列进行划分,应该怎么做呢?
当然,我们可以通过所希望的区间size大小求得输入序列对应的分位数,然后将分位数作为bins传给cut函数,这种方式是完全可行的。但是pandas提供了一种更简单的实现方式,qcut函数,即使用分位数对输入序列进行size大小的切分。
qcut的函数签名如下:
pandas.
qcut
(
x
,
q
,
labels=None
,
retbins=False
,
precision=3
,
duplicates='raise')
相比于cut函数,qcut函数中的参数会少一些,而且含义基本和cut函数一样。这里需要说明的就是参数q,其他参数的含义和cut函数是一样的。
对于qcut函数,会强制的将x的区间长度左延千分之一,以包含最小值,且区间强制是左开右闭的,没有参数控制。如果q为整数,代表将x按照元素个数进行q等分,即计算k*q分位数,k为整数,k*q介于0,1之间。所以,该函数最后所得到的区间就是对应的分位数,如下所示。
In [17]: pd.qcut([0,60,100,82,50],q=4,retbins=True)
Out[17]:
([(-0.001, 50.0], (50.0, 60.0], (82.0, 100.0], (60.0, 82.0], (-0.001, 50.0]]
Categories (4, interval[float64]): [(-0.001, 50.0] < (50.0, 60.0] < (60.0, 82.0] < (82.0, 100.0]],
array([ 0, 50, 60, 82, 100], dtype=int64))
当然,你也可以自定义q,比如[0,0.2,0.30,0.50,0.80,1],则区间边界就是对应的传入q的序列分位数。如下所示。
In [16]: pd.qcut([0,60,100,82,50],q=[0,0.2,0.30,0.50,0.80,1],retbins=True)
Out[16]:
([(-0.001, 40.0], (52.0, 60.0], (85.6, 100.0], (60.0, 85.6], (40.0, 52.0]]
Categories (5, interval[float64]): [(-0.001, 40.0] < (40.0, 52.0] < (52.0, 60.0] < (60.0, 85.6] <
(85.6, 100.0]],
array([ 0. , 40. , 52. , 60. , 85.6, 100. ]))
from numpy import nan as NA
from matplotlib import pyplot as plt
ages = [20,22,25,27,21,23,37,31,61,45,41,32]
#将所有的ages进行
分组
bins = [18,25,35,60,100]
#使用
pandas
中的
cut
对年龄
数据
进行
分组
cats =
pd
.
cut
(ages,bins)
#print(ca
在对
数据
进行处理分析时,有时需要对csv等表格
数据
中的某列
数据
进行
分组
,或者按数值大小重新分为几个类别,如需要将班级学生的成绩按90分为不及格,中,良,优四个等级,就可以利用python中的
pandas
工具,即
pd
.
cut
进行处理。① 如果是数组,长度要与分箱个数一致,比如 bins =[1, 2, 3, 4] 表示 (1,2], (2,3], (3,4],一共3个
区间
,则labels的长度也就是标签的个数也要是3。一个类似数组的对象,表示每个值的相应箱的 x。
pandas
.
cut
(x, bins, right=True, labels=None, retbins=False, precision=3, include_lowest=False, duplicates='raise') #0.23.4
功能:把一组
数据
分割成离散的
区间
参数:x:被切分的类数组(array-like)
数据
,必须是1维的(不能用DataFrame);
bins:bins是被切割后的
区间
(或者叫“桶”、“箱”、“面元”),有3中形式:一个int型.
Pandas
是什么?1、一个强大的分析结构化
数据
的工具集2、基础是NumPy,提供了高性能矩阵的运算3、应用在数学挖掘,
数据
分析。比如,学生成绩分析,股票
数据
分析等4、提供
数据
清洗功能Pands
数据
结构,主要分为两种,Series和DataFrame1、类似
一维
数组的对象2、通过list构建Seriesser_obj=
pd
.Series(rang(10))3、由
数据
和索引组成索引在左,
数据
在右索引是自动创建的4、获取
数据
和索引5、预览
数据
(取前几个)ser_obj.head(n)6、通过索引获取
数据
7、索引与
数据
的对应关系仍保持在数组运算的结果中(过滤series中的
数据
)8、通过dict构建
数值
数据
在
数据
分析中很常见。 通常,您拥有连续的、非常大的比例或高度偏斜的数值
数据
。有时,将这些
数据
分成离散的
区间
会更容易。 当值被划分为有意义的类别时,这有助于执行描述性统计。例如,我们可以将确切的年龄划分为幼儿、儿童、成人和老年人。
Pandas
内置的
cut
() 函数是将数值
数据
转换为分类
数据
的好方法。
参数及解释
pandas
.
cut
(x, bins, right=True, labels=None, retbins=False,\
1、
pd
.
cut
函数有7个参数,主要用于对
数据
从最大值到最小值进行等距划分
pandas
.
cut
(x, bins, right=True, labels=None, retbins=False, precision=3, include_lowest=False)
x : 输入待
cut
的
一维
数组
bins :
cut
的段数,一般为整型,但也可以为序列向量。
right :...
功能:数值型变量转变为因子变量
cut
将x的范围划分为若干个
区间
,并根据这些
区间
对x中的值进行编码。最左边的
区间
对应于第一级,第二左的
区间
对应第二级。
cut
(x, breaks, labels = NULL,
include.lowest = FALSE, right = TRUE, dig.lab = 3,
ordered_result = FALSE, ...)
x:数值型向量
break 可以为自定义的
分组
也可以为大于等于2的数字,如果是数字,则软件会自动均分数值间的距离,如果不...
df =
pd
.DataFrame(data = np.random.randint(0,150,size = (100,3)),
columns=['Python','Tensorflow','Keras'])
# 1、等宽分箱
pd
.
cut
(df.Python,bins = 3)
# 指定宽度分箱
pd
.
cut
(df.Keras,#分箱
数据
bins = [0,60,90,12..
# 2) False:左闭右开,[ , )
pd
.
cut
(np.array([1, 7, 5, 4, 6, 3]), [1, 4, 6, 10], right=True)
pd
.cu
Python实现连续
数据
的离散化处理主要基于两个函数,
pandas
.
cut
和
pandas
.q
cut
,前者根据指定分界点对连续
数据
进行分箱处理,后者则可以根据指定箱子的数量对连续
数据
进行等宽分箱处理,所谓等宽指的是每个箱子中的
数据
量是相同的。下面简单介绍一下这两个函数的用法:
# 导入
pandas
包
import
pandas
as
pd
ages = [20, 22, 25, 27, 21, 23, 37, 31, 61, 45, 41, 32] # 待分箱
数据
bins = [18, 25, 35,.
x:待划分的
数据
y:判断依据(
区间
)
right:逻辑值,默认为
区间
左开右闭;若为FALSE,则左闭右开。(知识补充:开
区间
是不包括端点(a,b),闭
区间
是包括端点[a,b]。)
include.lowest:逻辑值,include.lowest=TRUE,第一个
区间
包含左端点,最后一个
区间
包含右端点。
#通过
cut
,简化多重if语句
1.使用 if 函数:
pandas
.
cut
用来把一组
数据
分割成离散的
区间
。比如有一组年龄
数据
,可以使用
pandas
.
cut
将年龄
数据
分割成不同的年龄段并打上标签。
pandas
.
cut
(x, bins, right=True, labels=None, retbins=False, precision=3, include_lowest=False, duplicates='raise') #0.23.4
用
pandas
将
数据
划分
区间
在
数据
分析的过程中,经常会遇到:年龄,收入,价格以及类似的
数据
,在
数据
分析前,需要将这些
数据
划分到一系列
区间
中,再将
区间
进行不同的编码,对编码后的
数据
进行分析。
在
pandas
中可以使用
pandas
.
cut
()方法实现对
数据
的
区间
划分,以及对
区间
进行标记。
案例
数据
以name,age,score为例,使用
pandas
.
cut
()方法对age、score进行
区间
划分。
import
pandas
as
pd
import numpy as np
df =
pd
.DataF