如何在Dask中实现等宽分箱特征工程?求替代KBinsDiscretizer方案
Dask全局等宽分箱的并行实现方案
核心逻辑
要实现全局统一的等宽分箱,必须先获取数据集的全局最小值和全局最大值,计算出统一的分箱区间后,再对全量数据做并行分箱映射——这就避开了map_partitions单独处理分区的局限性。
分步实现代码
计算全局统计量
Dask原生支持并行计算全局极值,直接调用即可:import dask.dataframe as dd import pandas as pd # 假设df是你的Dask DataFrame,target_col是要分箱的列名 n_bins = 6 # 自定义分箱数量 min_val = df["target_col"].min().compute() max_val = df["target_col"].max().compute() bin_width = (max_val - min_val) / n_bins生成分箱边界并并行分箱
基于全局统计量生成统一边界后,用map_partitions调用pandas的cut函数完成分区内的并行分箱:# 生成等宽分箱边界 bins = [min_val + i * bin_width for i in range(n_bins + 1)] # 修正最后一个边界为最大值,规避浮点精度误差 bins[-1] = max_val # 定义分区内的分箱处理函数 def process_partition(partition): partition["target_col_bin"] = pd.cut( partition["target_col"], bins=bins, labels=False, include_lowest=True # 确保最小值被包含在第一个区间 ) return partition # 应用到所有分区,指定元数据保证类型正确 df_binned = df.map_partitions( process_partition, meta=df.dtypes.append(pd.Series(dtype="int64", name="target_col_bin")) )
额外优化
- 如果需要区间标签而非数字编号,将
labels参数替换为自定义的区间字符串列表即可,比如labels=[f"[{bins[i]:.1f}, {bins[i+1]:.1f})" for i in range(n_bins)] - 若要优化存储和后续计算性能,可以把分箱列转为分类类型:
df_binned["target_col_bin"] = df_binned["target_col_bin"].astype("category")
内容的提问来源于stack exchange,提问作者ps0604
相关产品推荐
相关产品推荐

