在数据分析与预处理过程中,数据分箱是一项非常实用的操作,它可以将连续型数据划分为若干个离散的区间,也能对文本类的非数值数据进行归类整合,方便后续做统计分析或者模型训练。Pandas作为Python生态中最常用的数据处理库,提供了多种实现数据分箱的方法,能够覆盖年龄分类、非数值数据分组等不同场景的需求。

什么是数据分箱
数据分箱简单来说就是把数据按照特定的规则划分到不同的组里,这些组就被称为箱。根据处理的数据类型不同,分箱可以分为两种常见场景:一种是针对连续数值的分箱,比如把年龄划分为少年、青年、中年、老年几个区间;另一种是针对非数值文本的分箱,比如把用户的职业划分为技术类、运营类、其他类几个组别。
连续数值的年龄分箱实现
对于年龄这类连续数值数据,Pandas中最常用的是cut函数,它可以根据指定的区间边界,把数值划分到对应的区间中。
等宽分箱
等宽分箱是指每个分箱的数值区间长度相同,比如把年龄按照10岁为一个区间划分。
import pandas as pd
import numpy as np
# 生成示例年龄数据
age_data = pd.DataFrame({
"age": np.random.randint(10, 70, size=20)
})
print("原始年龄数据:")
print(age_data)
# 使用cut函数进行等宽分箱,bins指定区间数量
age_data["age_bin"] = pd.cut(age_data["age"], bins=5)
print("n等宽分箱结果:")
print(age_data)
# 查看每个分箱的数量
print("n各分箱数量统计:")
print(age_data["age_bin"].value_counts())
自定义区间分箱
实际业务中我们往往需要按照自定义的年龄区间划分,比如少年(0-17岁)、青年(18-40岁)、中年(41-60岁)、老年(61岁以上)。
# 自定义年龄区间边界
bins = [0, 17, 40, 60, 100]
labels = ["少年", "青年", "中年", "老年"]
# 使用cut函数指定bins和labels参数
age_data["age_category"] = pd.cut(age_data["age"], bins=bins, labels=labels)
print("自定义区间分箱结果:")
print(age_data[["age", "age_category"]])
# 统计各年龄分类的数量
print("n各年龄分类统计:")
print(age_data["age_category"].value_counts())
非数值数据的分箱处理
对于文本类的非数值数据,Pandas的cut函数不再适用,我们可以使用map函数或者replace函数实现分组,也可以使用qcut函数结合编码后的数值做分箱,不过更常用的是自定义映射规则的方式。
使用map函数实现非数值分箱
比如我们有一组用户的职业数据,需要把职业划分为技术类、运营类、其他类三个组别。
# 生成示例非数值数据
user_data = pd.DataFrame({
"job": ["程序员", "产品经理", "运营专员", "测试工程师", "行政", "设计师", "运维工程师", "HR"]
})
print("原始职业数据:")
print(user_data)
# 定义职业到分箱类别的映射规则
job_map = {
"程序员": "技术类",
"测试工程师": "技术类",
"运维工程师": "技术类",
"产品经理": "运营类",
"运营专员": "运营类",
"设计师": "运营类",
"行政": "其他类",
"HR": "其他类"
}
# 使用map函数应用映射规则
user_data["job_category"] = user_data["job"].map(job_map)
print("n职业分箱结果:")
print(user_data)
# 统计各职业分类的数量
print("n各职业分类统计:")
print(user_data["job_category"].value_counts())
使用replace函数实现非数值分箱
如果非数值数据的分组规则比较简单,也可以使用replace函数批量替换实现分箱。
# 生成示例城市数据
city_data = pd.DataFrame({
"city": ["北京", "上海", "广州", "深圳", "杭州", "成都", "武汉", "南京"]
})
print("原始城市数据:")
print(city_data)
# 定义替换规则,一线城市归为一组,新一线城市归为一组
replace_rule = {
"北京": "一线城市",
"上海": "一线城市",
"广州": "一线城市",
"深圳": "一线城市",
"杭州": "新一线城市",
"成都": "新一线城市",
"武汉": "新一线城市",
"南京": "新一线城市"
}
city_data["city_level"] = city_data["city"].replace(replace_rule)
print("n城市分箱结果:")
print(city_data)
分箱操作的注意事项
- 使用
cut函数做数值分箱时,默认区间是左开右闭的,如果需要左闭右开,可以设置参数right=False。 - 自定义分箱区间时,区间边界要覆盖所有可能出现的数据值,避免出现数据无法匹配到任何分箱的情况。
- 使用
map函数做非数值分箱时,如果原数据中有映射规则里没有的值,对应结果会显示为NaN,需要提前处理缺失的映射关系。 - 分箱后的结果如果是区间类型,可以通过
astype(str)转换为字符串类型,方便后续存储或者展示。
总结
Pandas提供了灵活的数据分箱方法,针对年龄这类连续数值数据,优先使用cut函数,既可以快速实现等宽分箱,也可以自定义区间和标签;针对非数值文本数据,使用map或者replace函数自定义映射规则是最直接有效的方式。掌握这些分箱技巧,能够帮助开发者更高效地完成数据预处理工作,为后续的数据分析和建模打下良好的基础。