上一篇文章是对分箱的简单介绍(数据分箱:科学分类的简单指南),现在我们来学习他的代码是怎么实现的吧!
1. 分箱的Python代码实现
准备工作:安装库
如果你还没安装pandas
和numpy
,先运行以下命令安装:
pip install pandas numpy
示例1:等宽分箱(Equal Width Binning)
场景:把年龄分成3个等宽的组(比如0-30, 30-60, 60-90)。
数学逻辑:
宽度 = (最大值 - 最小值) / 箱数
import pandas as pd
# 示例数据
data = {'年龄': [15, 22, 34, 45, 60, 75, 88]}
df = pd.DataFrame(data)
# 等宽分箱:分3个箱
df['等宽分箱'] = pd.cut(df['年龄'], bins=3, labels=['青年', '中年', '老年'])
print(df)
输出:
关键参数:
-
bins=3
:分3个箱。 -
labels=['青年', '中年', '老年']
:自定义箱的标签。
示例2:等频分箱(Equal Frequency Binning)
场景:让每个箱里的数据量大致相同(比如分成3组,每组2-3人)。
数学逻辑:
-
用分位数(quantile)划分边界。
# 等频分箱:分3个箱
df['等频分箱'] = pd.qcut(df['年龄'], q=3, labels=['低龄', '中龄', '高龄'])
print(df)
输出:
关键参数:
-
q=3
:按3分位数分箱(即33.3%分位、66.6%分位)。
示例3:自定义边界分箱
场景:手动指定分箱边界(比如0-20=儿童,20-40=青年,40+=中年)。
# 自定义分箱边界
bins = [0, 20, 40, 100]
labels = ['儿童', '青年', '中年']
df['自定义分箱'] = pd.cut(df['年龄'], bins=bins, labels=labels)
print(df)
输出:
示例4:处理边界值(左闭右开 vs 左开右闭)
默认情况下,pd.cut
是左闭右开(即 20 ≤ x < 40
),但可以通过right=False
调整为左开右闭。
# 左开右闭分箱(20 < x ≤ 40)
df['左开右闭分箱'] = pd.cut(df['年龄'], bins=[0, 20, 40, 100], labels=['A', 'B', 'C'], right=False)
print(df)
输出:
示例5:分箱后统计频数
想知道每个分箱里有多少数据?用value_counts
:
# 统计等宽分箱的频数
print(df['等宽分箱'].value_counts())
# 输出:
# 青年 3
# 中年 2
# 老年 2
输出:
2. 注意事项
-
缺失值处理:如果数据有NaN,分箱会报错,需要先填充或删除:
df['年龄'].fillna(df['年龄'].mean(), inplace=True) # 用均值填充缺失值
-
标签和边界对齐:
labels
的数量必须比bins
少1(比如3个边界对应2个标签)。 -
非数值数据:如果数据是文本(如"高/中/低"),需要先编码成数字再分箱。
3. 完整代码示例
import pandas as pd
# 数据
data = {'年龄': [15, 22, 34, 45, 60, 75, 88]}
df = pd.DataFrame(data)
# 等宽分箱
df['等宽分箱'] = pd.cut(df['年龄'], bins=3, labels=['青年', '中年', '老年'])
# 等频分箱
df['等频分箱'] = pd.qcut(df['年龄'], q=3, labels=['低龄', '中龄', '高龄'])
# 自定义分箱
df['自定义分箱'] = pd.cut(df['年龄'], bins=[0, 20, 40, 100], labels=['儿童', '青年', '中年'])
# 输出结果
print(df)
# 统计频数
print("\n等宽分箱频数:")
print(df['等宽分箱'].value_counts())
输出:
4. 数学小课堂
-
等宽分箱:类似于把一根绳子平均剪成几段。
数学公式:宽度 = (max - min) / n
-
等频分箱:类似于按人数均分教室座位。
数学概念:分位数(Quantile)