如何导出分箱区间生成Python宏实现pandas变量分箱评分
代码问题排查
- 逻辑运算符错误:判断非特殊、非缺失分箱时用了
or,这个条件永远为真(一个值不可能同时等于Special和Missing,所以两个不等判断至少有一个成立),导致Special和Missing的分支永远不会执行。这里要把or改成and。 - 整列赋值错误:你在循环中直接对
df_bin_edges['lower_limit']这类整列做赋值,每次赋值都会覆盖整张表的对应列,最终所有行的结果都会等于最后一次循环的赋值,这就是你得到全表都是98.5、99.5的核心原因。你需要只对当前匹配的单行/筛选后的子集赋值,不能直接操作整列。 - 条件逻辑错误:第二个判断分支和第一个分支的触发条件完全一致(都是Index0),永远不会被执行,你原本要判断的是右边界为inf的情况,而不是Index0。
- 缺失值处理不符合规则:你给Missing的上下限赋值为空字符串,和你要求的
np.nan不符。
优化实现方案
用pandas的行级apply处理,比嵌套循环代码更简洁、执行效率更高,完全符合你给出的提取规则:
import pandas as pd import re import numpy as np def extract_bin_edges(row): bin_val = row['Bin'] # 特殊值处理 if bin_val == 'Special': return pd.Series([-999999999, -999999999]) if bin_val == 'Missing': return pd.Series([np.nan, np.nan]) # 提取区间内的数字 nums = re.findall(r"[-+]?\d*\.\d+|\d+", bin_val) nums = list(map(float, nums)) # 区间类型判断 if '[-inf' in bin_val: # 左无穷区间 return pd.Series([-999999990, nums[0]]) elif 'inf)' in bin_val: # 右无穷区间 return pd.Series([nums[0], 999999990]) elif len(nums) == 2: # 普通闭开区间 return pd.Series(nums) else: return pd.Series([np.nan, np.nan]) # 直接对整张表应用函数,生成上下限列 df_bin_edges[['lower_limit', 'upper_limit']] = df_bin_edges.apply(extract_bin_edges, axis=1)
如果需要基于提取的分箱结果自动生成每个变量的分箱函数,可以参考如下逻辑:
def generate_binner(feature_name, bin_df): # 提取当前变量的有效分箱边界,排除Special和Missing valid_bins = bin_df[(bin_df['feature_name'] == feature_name) & (~bin_df['Bin'].isin(['Special', 'Missing']))].sort_values('Index') bins = valid_bins['lower_limit'].tolist() + [valid_bins['upper_limit'].max()] labels = valid_bins['Bin'].tolist() # 生成分箱函数 def binner(x): if pd.isna(x): return 'Missing' # 可自行添加Special值判断逻辑,比如x == -999时返回'Special' return pd.cut([x], bins=bins, labels=labels, include_lowest=True)[0] return binner # 示例:生成var1的分箱函数并调用 var1_binner = generate_binner('var1', df_bin_edges) print(var1_binner(2.3)) # 输出[1.50, 2.50)
内容的提问来源于stack exchange,提问作者Zenvega
相关产品推荐
相关产品推荐

