【问题标题】:Overflow warnings when performing multiply on numpy masked arrays在 numpy 掩码数组上执行乘法时出现溢出警告
【发布时间】:2012-09-12 16:05:08
【问题描述】:

我有一个应用程序正在从 netcdf 文件中读取 32 位浮点数据,其中使用了默认的 netcdf 填充值,即 9.96920996839e+36。在应用程序中的特定点,对从输入数据创建的 float32 类型掩码数组执行基本缩放(乘法)操作,因此:

x = marr * scale   # or, equivalently, x = ma.multiply(marr,scale)

此操作会引发“在乘法中遇到溢出”警告,可能是因为填充值和比例的乘积超过了 32 位浮点数的最大值。已知掩码数组中的其他值很小。那么问题是,为什么 numpy 甚至计算输入数组中被屏蔽元素的乘积?当然这些都应该被忽略,对吧?

当它发生时,警告可以被忽略,因为输出数组中的相应值仍然被标记为被屏蔽。但是知道这是 numpy 中的错误还是“按设计工作”会很有趣。

下面的代码片段说明了这种行为。

import numpy as np
import numpy.ma as ma
arr = [9.96920996839e+36, 1.123, 2.345, 9.96920996839e+36]
marr = ma.masked_values(np.array(arr, dtype='float32'), 9.96920996839e+36)
x = marr * 128.0

正如预期的那样,如果掩码数组的类型为 float64,则不会出现溢出警告(尽管如果比例因子足够大,可能会出现)。同样,如果填充值较小,则警告会消失,例如-1.0e20,用于 float32 情况。

从表面上看,当使用较大的填充值(非常接近 32 位 f.p. 值的最大值)时,numpy 似乎无法识别掩码值。

TIA,
菲尔

【问题讨论】:

    标签: numpy


    【解决方案1】:

    那么问题是,为什么 numpy 还要计算输入数组中被屏蔽元素的乘积?当然这些都应该被忽略,对吧?

    唉,不。在当前实现中,对整个数组应用任何操作,然后重新应用掩码。

    我知道这听起来会适得其反,但与其他方法相比,它是一种更强大且效率更低的替代方案。最初,仅在适当的域上应用该操作会很好,但该域的计算可能会变得非常棘手(pow 存在一些大问题)。而且,额外的测试会破坏已经很可怜的性能。

    最近引入了一种新方法,其中 numpy 函数接受可选参数 where,这可能会有所帮助...但也有讨论直接在 C 级别引入对缺失/忽略值的支持,即可能是要走的路。

    【讨论】:

    • 非常感谢您对“幕后”发生的事情的额外见解。知道这一点后,我就可以应用一些适当的防御性编码。
    • @Phil 相信我,np.ma 相当笨重和缓慢并且急需改进,请在 numpy 邮件列表上发送想法和/或请求(或通过聊天发送消息)。但它有效。有点。
    【解决方案2】:

    可能是一个错误。上一行有:

    np.seterr(divide='ignore', invalid='ignore')
    

    这表明它旨在处理 0 或 NaN 的掩码,但不是非常大的值。应该是:

    np.seterr(divide='ignore', invalid='ignore', over='ignore')
    

    也可以处理大的掩码值。

    请注意,numpy.ma 操作通常对数组中的所有值进行操作,包括掩码值;这大概是因为效率和广播问题。

    【讨论】:

    • 感谢您的及时回复。是的,我发现了 seterr 函数提供的选项,尽管这些选项可能只是确定遇到数字错误时要采取的措施。正如你所建议的,可能是一个错误。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-30
    • 2022-11-09
    相关资源
    最近更新 更多