You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于Pandas列动态创建分箱:使观测数约为总计数的1%

Pandas数值列动态分箱实现方案

数据基础信息

Total rows 34149
Mean 4112195398.901
Min -1687500000
Median 44531800
Max 56956420100000

注:该列无零值

分箱规则

  • 所有负值归为-1分箱
  • 20000000以内采用1000000的分箱宽度
  • 20000000以上动态调整分箱宽度,使每个分箱的观测数(NOBS)约为总计数的1%,即当观测数低于总计数1%时调整宽度满足要求

已实现的前两类分箱代码

df_ = df['Col1'].dropna()
df_1 = pd.Series(np.where(df_ < 0, -1, pd.Series(df_/1000000).astype(int)))

df_2 = pd.DataFrame(df_1, columns=['Bins'])
df_bins = df_2.value_counts(sort=False).reset_index(name='NOBS')
df_bins['Percentage'] = (df_bins['NOBS']/df_bins['NOBS'].sum())*100

现有分箱输出示例

Bins NOBS Percentage
   -1    195   0.943
    0   2155  10.420
    1   1594   7.707
    2   1209   5.846
    3    970   4.690
    ...

第三类动态分箱实现方法

实现思路

  1. 从现有分箱结果中筛选出20000000以上的数据(对应df_bins中Bins>20的行,因20000000/1000000=20)
  2. 计算目标观测数:总数据量的1%,即target_nobs = int(len(df_) * 0.01)
  3. 迭代合并相邻分箱,直到每个分箱的观测数接近目标值
  4. 将处理后的动态分箱与前两类分箱合并,保持分箱为整数格式

具体代码实现

import pandas as pd
import numpy as np

# 提取2000万以上的分箱数据
above_20m = df_bins[df_bins['Bins'] > 20].copy().reset_index(drop=True)
# 计算目标观测数:总条数的1%
target_nobs = int(len(df_) * 0.01)

# 动态合并分箱
merged_bins = []
current_bin_start = above_20m['Bins'].iloc[0]
current_nobs = above_20m['NOBS'].iloc[0]

for i in range(1, len(above_20m)):
    if current_nobs + above_20m['NOBS'].iloc[i] < target_nobs:
        # 合并到当前分箱
        current_nobs += above_20m['NOBS'].iloc[i]
    else:
        # 保存当前分箱
        merged_bins.append({
            'Bins': current_bin_start,
            'NOBS': current_nobs,
            'Percentage': (current_nobs / len(df_)) * 100
        })
        # 重置当前分箱参数
        current_bin_start = above_20m['Bins'].iloc[i]
        current_nobs = above_20m['NOBS'].iloc[i]

# 添加最后一个未完成合并的分箱
merged_bins.append({
    'Bins': current_bin_start,
    'NOBS': current_nobs,
    'Percentage': (current_nobs / len(df_)) * 100
})

# 转换为DataFrame
merged_bins_df = pd.DataFrame(merged_bins)

# 合并前两类分箱和动态分箱结果
final_bins = pd.concat([
    df_bins[df_bins['Bins'] <= 20],
    merged_bins_df
]).reset_index(drop=True)

# 重新计算百分比,避免浮点误差导致总和不为100%
final_bins['Percentage'] = (final_bins['NOBS'] / final_bins['NOBS'].sum()) * 100

代码说明

  • 分箱标识采用起始分箱的整数值,若需要范围形式(如"21-30"),只需修改merged_bins中的'Bins'字段格式即可
  • 合并逻辑优先保证分箱观测数接近目标值,若最后一个分箱观测数不足1%,直接保留为单独分箱
  • 重新计算百分比可消除浮点运算带来的误差,确保总和始终为100%

内容的提问来源于stack exchange,提问作者Suhas_Pote

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 00:00:16