【Python】使用Pandas对数值进行分箱操作的4种方法

部署运行你感兴趣的模型镜像


分箱是一种常见的数据预处理技术,有时也被称为 分桶离散化,可用于将连续数据的间隔分组到“箱”或“桶”中。在本文中将介绍如何使用 Python的Pandas库中的4种方法对数值进行分箱。

首先,创建示例数据框

import pandas as pd
import numpy as np

def create_df():
  df = pd.DataFrame({'score': np.random.randint(0,101,1000)})
  return df

df = create_df()
df.head()

df
上面数据表示1000名学生的0到100分的考试分数。而我们的任务是将数字分数分为值“A”、“B”和“C”的等级,其中“A”是最好的,“C”是最差的。

方法1:between & loc

Pandas.between方法返回一个包含True的布尔向量,用来对应的Series元素位于边界值left和right之间。其中有三个参数“

  • left:左边界
  • right:右边界
  • inclusive:要包括哪个边界。可接受的值为 {“both”、“neither”、“left”、“right”}。

我们根据以下间隔规则将学生的分数分为等级:

  • A: (80, 100]
  • B: (50, 80]
  • C: [0, 50]

其中方括号[和圆括号)分别表示边界值是包含的和不包含的。我们需要确定哪个分数在感兴趣的区间之间,并为其分配相应的等级值。注意看下面的不同的参数表示是否包含边界

df.loc[df['score'].between(0, 50, 'both'), 'grade'] = 'C'
df.loc[df['score'].between(50, 80, 'right'), 'grade'] = 'B'
df.loc[df['score'].between(80, 100, 'right'), 'grade'] = 'A'
df.head()

between
以下是每个分数区间的人数统计:
value_counts
注意:此方法需要为每个bin编写处理的代码,因此它仅适用于bin很少的情况

方法2:cut

使用cut也可以将值分类为离散的间隔。此函数对于从连续变量到分类变量很有用。cut的参数如下:

  • x:要分箱的数组。必须是一维的。
  • bins:标量序列:定义允许非均匀宽度的 bin 边缘。
  • labels:指定返回的 bin 的标签。必须与上面的 bins 参数长度相同。
  • include_lowest: (bool) 第一个区间是否应该是左包含的。

代码如下:

bins = [0, 50, 80, 100]
labels = ['C', 'B', 'A']
df['grade'] = pd.cut(x = df['score'], bins = bins, labels = labels, include_lowest = True)
df.head()

cut
这样就创建一个包含bin边界值的bins列表和一个包含相应bin标签的标签列表。
查看每个区段的人数:
value_counts

方法3:qcut

qcut可以根据排名或基于样本分位数将变量离散为大小相等的桶。qcut的参数如下:

  • x:要分箱的输入数组。必须是一维的。
  • q:分位数。10 表示十分位数,4 表示四分位数等。也可以是交替排列的分位数,例如[0, .25, .5, .75, 1.] 四分位数。
  • labels:指定bin的标签。必须与生成的bin长度相同。
  • retbins: (bool) 是否返回 (bins, labels)。

在前两个示例中,为每个级别定义了分数间隔,这里使得每个级别的学生数量不均匀。在下面的示例中,将尝试将学生分类为3个具有相等(大约)数量的分数等级。示例中有1000名学生,因此每个分箱应该有大约333名学生。

df['grade'],cut_bin = pd.qcut(df['score'], q=3, labels=['C', 'B', 'A'], retbins=True)
df.head()

pcut
如果retbins设置为 True, 则会返回 bin 边界:
retbins
可以看到分数间隔如下:

  • C:[0, 36]
  • B:(36, 68]
  • A:(68, 100]

再次使用.value_counts()检查每个等级有多少学生。理想情况下,每个箱应该有大约 333 名学生。
value_counts

方法4:value_counts

虽然 pandas的.value_counts通常用于计算系列中唯一值的数量,但它也可用于使用bins参数将值分组到半开箱中。
半开箱
需要强调的是:

  • 默认情况下,.value_counts按值的降序对返回的系列进行排序。将sort设置为False以按其索引的升序对系列进行排序。
  • 返回值的第一列是series索引,是指每个 bin 的区间范围,其中方括号[和圆括号)分别表示边界值是包含的和不包含的。返回的第二列是series的值,表示每个bin中有多少条记录。
  • 与.qcut 不同,每个bin中的记录数不一定相同(大约)。.value_counts不会将相同数量的记录分配到相同的类别中,而是根据最高和最低分数将分数范围分成3个相等的部分。分数的最小值为0,最大值为100,因此这3个部分中的每一个都大约在33.33范围内。这也解释了为什么bin的边界是 33.33 的倍数。

还可以通过传入边界列表来定义bin边界:
传入边界
这里的输出结果与方法1和2的结果相同。

补充材料

  1. https://colab.research.google.com/drive/1yWTl2OzOnxG0jCdmeIN8nV1MoX3KQQ_1?usp=sharing

您可能感兴趣的与本文相关的镜像

Python3.11

Python3.11

Conda
Python

Python 是一种高级、解释型、通用的编程语言,以其简洁易读的语法而闻名,适用于广泛的应用,包括Web开发、数据分析、人工智能和自动化脚本

<think> 我们使用pandas.qcut进行分箱并替换原特征值,主要步骤: 1. 使用pd.qcut()函数,指定q(分箱数)、labels(自定义标签)等参数 2. 将返回的分箱结果(分类对象)赋值给原数据列,即可替换原特征值 3. 注意处理边界重复问题(通过duplicates参数) 具体方法如下: </think> # 使用pandas.qcut进行分箱并替换特征值 在数据预处理中,使用`pandas.qcut`进行分箱并替换原有特征值是一种常见操作,尤其适用于将连续变量转换为分类变量。以下是详细实现方法: ## 基础实现步骤 ```python import pandas as pd import numpy as np # 创建示例数据 data = pd.DataFrame({ 'income': np.random.normal(5000, 2000, 1000), 'score': np.random.randint(300, 850, 1000) }) # 对income列进行4等频分箱并替换原值 data['income_bin'] = pd.qcut( data['income'], q=4, # 4等分 labels=['低收入', '中低收入', '中高收入', '高收入'] # 自定义标签 ) # 查看结果分布 print(data['income_bin'].value_counts()) ``` 输出示例: ``` 中低收入 250 低收入 250 高收入 250 中高收入 250 Name: income_bin, dtype: int64 ``` ## 关键参数解析 1. **q参数**:指定分箱数量或分位数列表 - `q=4`:4等分 - `q=[0, 0.3, 0.7, 1]`:自定义分位数点 2. **labels参数**:将分箱结果替换为分类标签 ```python data['score_bin'] = pd.qcut( data['score'], q=4, labels=['D级', 'C级', 'B级', 'A级'] # 替换为等级标签 ) ``` 3. **retbins参数**:获取分箱边界用于后续处理 ```python data['income_bin'], bins = pd.qcut( data['income'], q=4, labels=['低', '中低', '中高', '高'], retbins=True # 返回分箱边界 ) print("分箱边界:", bins) ``` ## 处理边界重复问题 当数据存在大量重复值时,需使用`duplicates`参数: ```python data['income_bin'] = pd.qcut( data['income'], q=4, labels=['低', '中低', '中高', '高'], duplicates='drop' # 自动删除重复边界 ) ``` ## 应用场景案例:信用评分分箱 ```python # 创建信用评分数据 credit_scores = np.random.randint(300, 850, 1000) # 分箱并替换 binned_scores = pd.qcut( credit_scores, q=[0, 0.2, 0.5, 0.8, 1], # 自定义分位数 labels=['高风险', '中风险', '良好', '优质'] ) # 合并到原数据 data['credit_rating'] = binned_scores # 查看分布 print(data.groupby('credit_rating').size()) ``` ## 机器学习流水线集成 在机器学习中保持分箱一致性: ```python # 训练阶段:计算并保存分箱边界 train_data = pd.read_csv('train.csv') _, income_bins = pd.qcut(train_data['income'], q=4, retbins=True) # 预测阶段:应用相同边界 test_data = pd.read_csv('test.csv') test_data['income_bin'] = pd.cut( # 注意改用cut固定边界 test_data['income'], bins=income_bins, labels=['低', '中低', '中高', '高'] ) ``` ## 最佳实践建议 1. **标签设计原则**: - 标签数量应与实际分箱数一致 - 业务可解释性优先(如:低/中/高) - 避免使用纯数字标签以防误解为数值 2. **异常值处理**: ```python # 添加显式边界包含极值 bins = [-np.inf, 1000, 5000, 10000, np.inf] data['income_bin'] = pd.cut(data['income'], bins, labels=labels) ``` 3. **内存优化**: ```python # 转换为category类型节省内存 data['income_bin'] = data['income_bin'].astype('category') ``` > 通过`pandas.qcut`实现的分箱转换,可在保持数据分布特征的同时显著提升逻辑回归等模型的性能[^2][^3]。分箱后的特征更符合线性模型假设,同时能降低异常值影响[^4]。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

镰刀韭菜

看在我不断努力的份上,支持我吧

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值