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

如何让seaborn.kdeplot对负值/零值具备鲁棒性?

问题描述

我有两个存储在原生Python列表中的浮点型变量:

x = [2.232, 2.331, 2.112...]
y = [-3.431, 2.213, -1.232...]

注意其中存在负值,调用kde时出现以下错误:

ZeroDivisionError: 0.0 cannot be raised to a negative power.

由于场景对绘图精度要求不高,我尝试给x和y的所有元素临时添加一个小值:

x = []
for i in range(len(raw_data)):
    x.append(float(raw_data[i][1])+.000000001)

但错误仍然存在,甚至尝试添加更大的值(0.1)也没用。

核心问题

有没有更可靠的方法确保kde调用对非零值具备鲁棒性?手动调整数据无效说明可能还有其他问题。

调用代码

seaborn.kdeplot(x,y)

错误详情

~\Anaconda3\lib\site-packages\statsmodels\nonparametric\bandwidths.py in bw_scott(x, kernel)
     53     A = _select_sigma(x)
     54     n = len(x)
---> 55     return 1.059 * A * n ** (-0.2)
     56 
     57 def bw_silverman(x, kernel=None):

解决思路与方案

从错误栈来看,问题出在statsmodels的带宽计算函数bw_scott里,n ** (-0.2)报错,说明要么数据长度为0,要么数据的离散程度估计量为0,具体解决方法如下:

  • 检查数据有效性
    先确认x和y的长度是否一致且不为空,打印len(x)和len(y)即可。如果其中一个列表为空,或者两者长度不匹配,直接修正数据来源。

  • 排查数据方差
    如果某一列数据所有值完全相同(比如所有x值都是同一个数),会导致_select_sigma(x)返回0,触发计算错误。可以用以下代码检查方差:

    import numpy as np
    print(np.var(x), np.var(y))
    

    若方差为0,给该列添加极小的随机噪声(比固定加值更可靠):

    x = np.array(x) + np.random.normal(0, 1e-8, size=len(x))
    y = np.array(y) + np.random.normal(0, 1e-8, size=len(y))
    
  • 手动指定带宽
    绕开自动带宽计算逻辑,直接给kdeplot指定带宽参数:

    import seaborn as sns
    # 通过bw_adjust调整平滑程度,数值越大越平滑
    sns.kdeplot(x=x, y=y, bw_adjust=0.5)
    # 或者直接指定固定带宽值
    sns.kdeplot(x=x, y=y, bw_method=0.3)
    
  • 数据平移(可选)
    若担心负值影响(实际KDE本身支持负值),可以对数据进行平移,确保所有值为正且分布趋势不变:

    min_x = min(x)
    min_y = min(y)
    x_shifted = [val - min_x + 1e-6 for val in x]
    y_shifted = [val - min_y + 1e-6 for val in y]
    sns.kdeplot(x_shifted, y_shifted)
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 02:55:22