使用Fitter库循环检查数值列数据分布仅得单一结果的问题排查
问题分析与解决方案
代码存在的问题
- 绘图被覆盖:循环中每次调用
dist_fitter.summary()时,默认会在同一个绘图区域输出,后续列的绘图会直接覆盖之前的结果,最终仅显示最后一列的图表和汇总表。 - 拟合实例被覆盖:每次循环都重新赋值
dist_fitter变量,之前列的拟合实例会被覆盖,无法保留所有列的拟合结果。 - 缺失值处理不合理:直接用
fillna(0)填充缺失值可能严重扭曲原始数据分布,建议根据列的分布特性选择均值、中位数等更合理的填充方式。
修正后的代码
from fitter import Fitter import numpy as np import matplotlib.pyplot as plt df_numeric = df.select_dtypes(include=np.number).sample(n=5000) num_cols = df_numeric.columns.tolist() distr = ['cauchy', 'chi2', 'expon', 'exponpow', 'gamma', 'beta', 'lognorm', 'logistic', 'norm', 'powerlaw', 'rayleigh', 'uniform'] # 保存所有列的拟合结果,方便后续查看 fitter_results = {} for col in num_cols: # 用中位数填充缺失值,避免0值干扰分布 modif_col = df_numeric[col].fillna(df_numeric[col].median()).values # 过滤无穷值,避免拟合报错 modif_col = modif_col[np.isfinite(modif_col)] dist_fitter = Fitter(modif_col, distributions=distr) dist_fitter.fit() # 保存当前列的拟合实例 fitter_results[col] = dist_fitter # 创建新的绘图窗口,防止覆盖 plt.figure(figsize=(10, 6)) # 生成当前列的汇总表和绘图 dist_fitter.summary() # 显式展示绘图 plt.show() # 打印列名区分不同结果 print(f"=== 列 {col} 拟合完成 ===")
其他循环检查数据分布的方法
方法1:Scipy Stats批量拟合+可视化
import scipy.stats as stats import seaborn as sns for col in num_cols: data = df_numeric[col].dropna().values if len(data) == 0: continue plt.figure(figsize=(10, 6)) # 绘制直方图+核密度曲线 sns.histplot(data, kde=True, stat="density", alpha=0.6) # 拟合常见分布并绘制概率密度函数 dist_list = [stats.norm, stats.expon, stats.lognorm, stats.gamma] x = np.linspace(min(data), max(data), 1000) for dist in dist_list: params = dist.fit(data) pdf_curve = dist.pdf(x, *params) plt.plot(x, pdf_curve, label=f"{dist.name}") plt.title(f"列 {col} 分布拟合对比") plt.legend() plt.show()
方法2:快速可视化分布(无需精确拟合)
如果只是需要快速查看所有数值列的分布特征,可以用Pandas和Seaborn批量生成基础图表:
# 批量绘制直方图 df_numeric.hist(figsize=(15, 10), bins=20) plt.tight_layout() plt.show() # 批量绘制箱线图,查看异常值 plt.figure(figsize=(12, 8)) sns.boxplot(data=df_numeric) plt.xticks(rotation=45) plt.show()
内容的提问来源于stack exchange,提问作者mustafa00
相关产品推荐
相关产品推荐

