cut与qcut区别
- 1、pd.cut()
- 2、pd.qcut()
- 3、cut与qcut区别
Pandas提供了智能剪贴功能:pd.cut()与pd.qcut(),它们通常用于更方便直观地处理关系型或标签型数据,将数据进行分箱/离散化
1、pd.cut()
我们可以通过两种方式使用cut()函数:直接指定bin的数量,让Pandas为我们计算等大小的bin,或者我们可以按照自己的意愿手动指定bin的边缘
在cut()函数中,bin边缘的间距大小是相等的,每个bin或箱中的元素数量不均匀。例如,如果对年龄进行分箱,0-1岁是婴儿,1-12岁是孩子,12-18岁是青少年,18-60岁是成年人,60岁以上是老年人。所以我们可以设置:
bins=[0, 1, 12, 18, 60, 140]
labels=['infant', 'kid', 'teenager', 'grownup', 'senior citizen']
cut()的API如下:
pd.cut(x,bins,right,labels,retbins,precision,include_lowest,duplicates,ordered)
其参数及说明如下:
- x:需要进行分箱的数据,1D数组或系列类型,如果数据存在NaN则报错
- bins:分箱的边界,如果是单个整数,则表示基于数据中的最小值和最大值生成等间距间隔;也可以是自定义边界值的列表或数组
- right:是否包含最右边的数值,默认为True(右闭)
- labels:分箱的标签,长度保持与分箱数一致
- retbins:是否显示分箱的边界值,默认为False。当
bins为整数时设置True可以显示边界值 - precision:分箱边界的精度,默认3位小数
- include_lowest:是否包含最左边的数值,默认为False(左开)
- duplicates:默认为
raise,如果分箱的边界不唯一,则引发ValueError;指定drop则去重 - ordered:标签是否有序,默认为True,分类结果将被排序
以下是一个使用示例:
import pandas as pd
import numpy as np
# 数据准备
years = [2024, 2023, 2017, 2011, 2015, 2023, 2008, 2010]
df = pd.DataFrame(years, columns=['Year'])
基本使用如下:
# 左开右闭
print(pd.cut(df['Year'], bins=3, precision=0))

数据的年份范围是2008年到2024年(16个),当我们指定bins=3时,Pandas将它切分成3个等宽的bin,每个bin5-6年。需要注意的是,Pandas会自动将第一类的下限值丢失精度,以确保将2008年也包括在结果中
# 左闭右闭
print(pd.cut(df['Year'], bins=3, include_lowest=True, precision=0))

可以将标签参数指定为一个列表,而不是获得间隔,以便更好地分析:
# 指定分类标签
df['Label'] = pd.cut(df['Year'], bins=3, labels=['Old', 'Medium', 'New'], precision=0)
print(df)

如果指定labels=False,我们将得到bin的数字表示(从0依次开始递增):
df['Label'] = pd.cut(df['Year'], bins=3, labels=False)
print(df)

查看每个分箱中的值数量:
print(df['Label'].value_counts().reset_index())

显示分箱的边界值:
# 我们可以指定retbins=True一次性获得bin区间和边界值离散的序列,此时方法返回一个二元组
cut_series, cut_intervals = pd.cut(df['Year'], bins=3, retbins=True, precision=0)
# bin区间
print(cut_series)
# 分箱的边界值
print(cut_intervals)

我们也可以通过给bins参数传入一个列表来手动指定bin的边缘:
# 自定义bin边缘
print(pd.cut(df['Year'], bins=[2008, 2010, 2020, 2024], include_lowest=True))

这里,我们设置了include_lowest=True,默认情况下,它被设置为False,因此,当Pandas看到我们传递的列表时,它将把2008年排除在计算之外。因此,这里我们也可以使用任何小于2008的值
2、pd.qcut()
qcut()函数(Quantile-Cut)与cut()的关键区别在于,在qcut()中,每个bin中的元素数量将大致相同,但这将以不同大小的bin区间宽度为代价
在qcut()函数中,当我们指定q=5时,我们告诉Pandas将数据列切成5个相等的量级,即0-20%,20-40%,40-60%,60-80%和80-100%桶/箱
qcut()的API如下:
pd.qcut(x,q,labels,retbins,precision,duplicates)
其参数及说明如下:
- x:需要进行分箱的数据,1D数组或系列类型,如果数据存在NaN则保留
- q:分位数,例如4用于四分位,也可以指定为列表
[0,0.25,0.5,0.75,1] - 其他参数:同
pd.cut()
给数据注入一个缺失值,我们看下qcut()将如何处理一个包含NaN的数据集
# 添加NaN值
df.loc[0, 'Year'] = np.NaN
以下是一个使用示例:
# 左开右闭
print(pd.qcut(df['Year'], q=3))

你是否注意到,在输出结果中,NaN值也被保留为NaN?
指定分箱标签:
# 指定分箱标签
df['Label'] = pd.qcut(df['Year'], q=3, labels=['Old', 'Medium', 'New'])
print(df)

自定义分箱量级:
# 自定义分箱量级
print(pd.qcut(df['Year'], q=[0, 1 / 3, 2 / 3, 1]))

可以看到,分箱的边缘是不等宽的,因为它要容纳每个桶1/3的值,因此它要自己计算每个箱子的宽度来实现这一目标
3、cut与qcut区别
综上所述,现对cut()与qcut()方法的使用区别作如下总结:
cut()分箱边缘是等间距的,因此,箱中的元素数量不均;qcut()分箱箱中的元素数量是均匀的,因此,箱边缘不是等间距的cut()分箱数据如果存在NaN则报错;qcut()分箱则将存在的NaN保留
参考文章:https://geek-docs.com/pandas/pandas-tutorials/how-to-use-pandas-cut-and-qcut.html


















