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

含缺失数据的图表叠加线性回归时scipy.linregress返回nan问题求解

核心问题根因

  • 为什么linregress返回intercept=nan:Scipy的线性回归函数不会自动过滤数组中的缺失值(Excel空单元格读入pandas后默认转成的NaN),只要输入的x/y序列中存在哪怕一个空值,整个回归计算的输出结果都会是NaN,这是新手读取Excel做拟合最常见的踩坑点。
  • 为什么插入拟合列时报长度不匹配:你用过滤掉空值的有效数据计算拟合值时,得到的结果数组长度等于有效非空数据的行数,但原DataFrame(比如提到的cereal_df)的总行数是包含空单元格的全量长度,直接把短数组塞回全量DataFrame自然会触发长度不匹配错误。

分步可落地解决流程

  1. 第一步:先完成拟合前的数据清洗
    从Excel读入的数据中,空单元格会被pandas自动识别为NaN,需要先把用于拟合的两列(时间、金属损耗值)中同时非空的行单独筛选出来,不能直接拿整列喂给回归函数。

    import pandas as pd
    import numpy as np
    import matplotlib.pyplot as plt
    from scipy.stats import linregress
    
    # 沿用你之前使用的cereal_df即可,读入时空单元格会自动转NaN
    cereal_df = pd.read_excel("你的金属损耗测量数据.xlsx")
    # 替换成你实际表格里的对应列名
    valid_df = cereal_df.dropna(subset=["测量时间", "金属损耗量"])
    x_valid = valid_df["测量时间"]
    y_valid = valid_df["金属损耗量"]
    
  2. 第二步:用有效非空数据计算线性回归
    此时输入给回归函数的序列没有缺失值,计算结果不会再出现全nan的情况:

    # 输入为纯非空序列,回归结果正常
    res = linregress(x_valid, y_valid)
    print(f"线性回归结果: 斜率={res.slope:.2f}, 截距={res.intercept:.2f}, R²={res.rvalue**2:.2f}")
    
  3. 第三步:解决拟合列插入的长度不匹配问题
    不要直接把有效子集算出的短长度拟合值塞回原DataFrame,而是基于原DataFrame的全量时间列做矢量化计算,生成和原表长度完全一致的拟合值列:

    # ❌ 之前容易触发报错的写法
    # y_fit = res.slope * x_valid + res.intercept
    # cereal_df["拟合值"] = y_fit
    # 问题根源:y_fit只有有效数据的行数,比全量cereal_df短,必然报长度不匹配
    
    # ✅ 正确写法:基于原cereal_df的全量时间列计算拟合值
    cereal_df["拟合损耗值"] = res.slope * cereal_df["测量时间"] + res.intercept
    
  4. 第四步:在matplotlib图表上叠加趋势线
    绘图时matplotlib会自动跳过原始数据列中的空值点,直接使用刚生成的全量拟合值列画趋势线即可:

    # 绘制原始测量值散点
    plt.scatter(cereal_df["测量时间"], cereal_df["金属损耗量"], label="实际测量数据")
    # 叠加覆盖全时间范围的线性趋势线
    plt.plot(
        cereal_df["测量时间"], 
        cereal_df["拟合损耗值"], 
        color="crimson", 
        linewidth=2,
        label=f"线性趋势线 (R²={res.rvalue**2:.2f})"
    )
    plt.xlabel("测量时间")
    plt.ylabel("金属损耗量")
    plt.legend()
    plt.grid(alpha=0.3)
    plt.show()
    

新手避坑提示

  • 不管是用scipy.stats.linregress还是np.polyfit,两个函数本身都不会自动处理缺失值,只要输入序列混入NaN,输出结果就会全为nan,必须先主动筛出有效非空数据再喂给回归函数。如果习惯用np.polyfit完成拟合,逻辑完全一致:先筛出有效非空的x、y值计算拟合系数,再基于原DataFrame的全量x列生成拟合值列,同样可以避免结果为nan、列长度不匹配的问题。
  • 给DataFrame新增计算列时,优先基于原DataFrame的列做矢量化运算,不要把筛选子集上算出的短长度数组直接赋值回全量DataFrame,从根源上避免长度不匹配的报错。
  • 如果Excel里的空单元格是用文本符号(比如-、无数据)占位的,读入时要在pd.read_excel中加参数na_values=["-", "无数据"],把这些占位文本转成标准NaN,避免后续计算出现类型错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.24 10:45:04