本文目录导读:

我来详细介绍Python中使用Pandas进行数据分箱的几种方法。
等宽分箱(Equal-width Binning)
import pandas as pd
import numpy as np
# 创建示例数据
data = pd.DataFrame({
'age': [18, 25, 32, 45, 58, 63, 72, 28, 35, 51, 67, 22, 38, 55, 48]
})
# 方法1:使用cut()进行等宽分箱
data['age_group'] = pd.cut(data['age'], bins=3) # 分成3个等宽区间
print(data)
print("\n各分组统计:")
print(data['age_group'].value_counts().sort_index())
# 自定义分箱边界
bins = [0, 20, 30, 40, 50, 60, 100]
labels = ['0-20', '20-30', '30-40', '40-50', '50-60', '60+']
data['age_range'] = pd.cut(data['age'], bins=bins, labels=labels)
print("\n自定义边界分箱:")
print(data)
等频分箱(Equal-frequency Binning)
# 方法2:使用qcut()进行等频分箱
data['age_quantile'] = pd.qcut(data['age'], q=4, labels=['Q1', 'Q2', 'Q3', 'Q4'])
print(data)
# 查看各分组的数据量(应该基本相同)
print("\n各分组数量:")
print(data['age_quantile'].value_counts().sort_index())
实际业务场景案例
# 案例1:客户年龄段分析
customers = pd.DataFrame({
'customer_id': range(1, 21),
'age': [22, 35, 48, 55, 62, 28, 33, 41, 50, 67,
19, 44, 58, 72, 36, 51, 39, 46, 60, 25],
'purchase_amount': [120, 350, 280, 500, 450, 180, 320, 400, 380, 550,
100, 420, 480, 600, 300, 450, 260, 380, 520, 200]
})
# 年龄分组
age_bins = [0, 25, 35, 45, 55, 65, 100]
age_labels = ['18-25', '26-35', '36-45', '46-55', '56-65', '65+']
customers['age_group'] = pd.cut(customers['age'], bins=age_bins, labels=age_labels)
# 购买金额分层
amount_bins = [0, 200, 350, 500, 1000]
amount_labels = ['低消费', '中等消费', '高消费', 'VIP']
customers['consumption_level'] = pd.cut(customers['purchase_amount'],
bins=amount_bins, labels=amount_labels)
print("客户分层分析:")
print(customers)
# 交叉分析
cross_analysis = pd.crosstab(
customers['age_group'],
customers['consumption_level'],
values=customers['purchase_amount'],
aggfunc='mean'
)
print("\n年龄-消费交叉分析(平均消费额):")
print(cross_analysis)
自定义分箱规则
# 案例2:成绩等级评定
scores = pd.DataFrame({
'student': ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H'],
'score': [85, 92, 67, 45, 78, 95, 58, 73]
})
# 使用自定义函数进行分箱
def score_level(score):
if score >= 90:
return '优秀'
elif score >= 80:
return '良好'
elif score >= 70:
return '中等'
elif score >= 60:
return '及格'
else:
return '不及格'
scores['level'] = scores['score'].apply(score_level)
print("成绩等级评定:")
print(scores)
# 另一种方式:使用cut() + 自定义边界
bins = [0, 60, 70, 80, 90, 100]
labels = ['不及格', '及格', '中等', '良好', '优秀']
scores['level_v2'] = pd.cut(scores['score'], bins=bins, labels=labels, right=False)
print("\n使用cut()的另一种方式:")
print(scores)
连续变量分箱
# 案例3:收入水平分析
np.random.seed(42)
income_data = pd.DataFrame({
'employee_id': range(1, 31),
'salary': np.random.normal(8000, 3000, 30).astype(int)
})
# 确认没有负值
income_data['salary'] = np.abs(income_data['salary'])
# 方法1:使用百分位数动态分箱
percentiles = [0, 0.2, 0.4, 0.6, 0.8, 1.0]
bins = [income_data['salary'].quantile(p) for p in percentiles]
bins = list(set(bins)) # 去重
bins.sort()
income_data['salary_level'] = pd.cut(
income_data['salary'],
bins=bins,
labels=['低', '中低', '中等', '中高', '高']
)
print("收入水平分析:")
print(income_data)
# 方法2:使用qcut直接分频数
income_data['salary_quantile'] = pd.qcut(
income_data['salary'],
q=4, # 4等分
labels=['Q1', 'Q2', 'Q3', 'Q4']
)
print("\n分位数分组结果:")
print(income_data.groupby('salary_quantile')['salary'].agg(['min', 'max', 'mean']))
高级技巧:动态分箱
# 案例4:销售数据动态分箱
np.random.seed(42)
sales_data = pd.DataFrame({
'product': [f'Product_{i}' for i in range(1, 21)],
'sales_amount': np.random.randint(1000, 100000, 20)
})
# 基于数据分布动态确定分箱数
def dynamic_binning(data, column, method='auto'):
"""
动态分箱函数
method: 'auto' - 自动确定箱数, 'fixed' - 固定箱数
"""
if method == 'auto':
# 使用斯特吉斯公式确定箱数
n = len(data)
bins_count = int(np.ceil(np.log2(n) + 1))
bins = pd.cut(data[column], bins=bins_count)
else:
bins = pd.cut(data[column], bins=5) # 固定5箱
return bins
sales_data['sales_group'] = dynamic_binning(sales_data, 'sales_amount')
print("动态分箱结果:")
print(sales_data)
print("\n各箱统计:")
print(sales_data['sales_group'].value_counts().sort_index())
分箱后数据分析
# 对分箱结果进行统计分析
print("=== 分箱统计分析 ===")
# 1. 查看各箱的统计信息
stats = data.groupby('age_group')['age'].agg(['count', 'min', 'max', 'mean', 'std'])
print("各年龄组统计:")
print(stats)
# 2. 可视化分箱效果
import matplotlib.pyplot as plt
fig, axes = plt.subplots(1, 2, figsize=(12, 4))
# 原始数据分布
axes[0].hist(data['age'], bins=10, edgecolor='black')
axes[0].set_title('原始数据分布')
# 分箱后的分布
axes[1].bar(data['age_group'].value_counts().index,
data['age_group'].value_counts().values)
axes[1].set_title('分箱后分布')
axes[1].tick_params(axis='x', rotation=45)
plt.tight_layout()
plt.show()
注意事项
- 边界处理:使用
right=False参数控制区间是否包含右边界 - 空值处理:分箱前确保数据中没有NaN值
- 箱数选择:根据数据量级和业务需求合理选择箱数
- 标签设置:设置清晰的标签便于后续分析
这些案例涵盖了数据分箱的主要场景和技巧,可以根据实际需求选择合适的方法。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播