numpy计算无输入NaN却输出NaN问题求助
问题分析与解决方案
首先,咱们先明确:你遇到的情况是单独的log10和sqrt数组都没有NaN,但它们相乘后出现了NaN,这大概率不是输入数据的NaN问题,而是浮点数运算里的特殊值(无穷大/无穷小)导致的。
核心原因:inf * 0 或 -inf * 0 会产生NaN
numpy里,无穷大(inf)或者负无穷(-inf)和0相乘,结果会是np.nan,但单独检查inf的时候,np.isnan()会返回False——这就是你看到的“单独数组无NaN,相乘后有NaN”的根本原因。
举个简单例子验证:
import numpy as np a = np.array([np.inf]) b = np.array([0.0]) print(np.isnan(a), np.isnan(b)) # 输出:[False] [False] print(np.isnan(a * b)) # 输出:[True]
排查步骤
检查
log10和sqrt里是否存在无穷值
在代码里加上这两行,确认是否有inf或-inf:print("log10有无穷值?", np.isinf(log10).any()) print("sqrt有无穷值?", np.isinf(sqrt).any())定位产生NaN的具体位置
把你注释掉的那段循环打开,或者用numpy的where直接找索引:nan_indices = np.where(np.isnan(ttt)) print("产生NaN的索引:", nan_indices) print("对应log10值:", log10[nan_indices]) print("对应sqrt值:", sqrt[nan_indices])这时候你会看到,这些位置要么是
log10为-inf(因为log的值趋近于0,np.log10(0)会返回-inf),要么是sqrt为0(因为rot=2*g*DN*J_e趋近于0),两者相乘就得到了NaN。追溯原始数据的异常值
找到这些索引对应的原始数据(DN、J_e、v、k),看看是不是存在:DN极小或者为0?J_e极小或者为0?v极小导致(2.51*v)/(DN*np.sqrt(2*g*DN*J_e))趋近于0,加上后面的项后log整体趋近于0?
解决方法
针对找到的异常情况,给运算加一个“兜底”处理,避免出现inf和0相乘的情况:
比如:
- 给
log设置一个极小的下限,防止log10变成-inf:log = ((2.51 * v) / (DN * np.sqrt(2 * g * DN * J_e))) + (k / (3.71 * DN)) # 给log设置最小值,避免log10返回-inf log = np.maximum(log, 1e-10) log10 = np.log10(log) - 给
rot设置一个极小的下限,防止sqrt变成0:rot = 2 * g * DN * J_e rot = np.maximum(rot, 1e-10) sqrt = np.sqrt(rot) - 或者在相乘的时候直接处理特殊值:
# 先把log10里的-inf替换成一个合理的极小值,sqrt里的0替换成极小值 log10_clean = np.where(np.isinf(log10), -10, log10) sqrt_clean = np.where(sqrt == 0, 1e-10, sqrt) ttt = log10_clean * sqrt_clean
这样就能避免相乘后出现NaN的情况了。
内容的提问来源于stack exchange,提问作者JohPel
相关产品推荐
相关产品推荐

