Python案例如何用Pandas做数据分箱

wen python案例 1

本文目录导读:

Python案例如何用Pandas做数据分箱

  1. 等宽分箱(Equal-width Binning)
  2. 等频分箱(Equal-frequency Binning)
  3. 实际业务场景案例
  4. 自定义分箱规则
  5. 连续变量分箱
  6. 高级技巧:动态分箱
  7. 分箱后数据分析
  8. 注意事项

我来详细介绍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()

注意事项

  1. 边界处理:使用right=False参数控制区间是否包含右边界
  2. 空值处理:分箱前确保数据中没有NaN值
  3. 箱数选择:根据数据量级和业务需求合理选择箱数
  4. 标签设置:设置清晰的标签便于后续分析

这些案例涵盖了数据分箱的主要场景和技巧,可以根据实际需求选择合适的方法。

抱歉,评论功能暂时关闭!