【问题标题】:Numpy vs Python floating point calculations produce different resultsNumpy 与 Python 浮点计算产生不同的结果
【发布时间】:2015-10-26 17:44:47
【问题描述】:

我有一个浮动列表,如下所示:

u = [[1.2, 1.534, 23.5, ...], [0.2, 11.5, 3.3223, ...], ...]

使用 Python 计算一个新列表(高度和宽度是列表的维度,u2 是设置为 0.0 的浮点列表的列表):

for time in xrange(start, stop):
    for i in xrange(1,height-1):
        for j in xrange(1, width-1):
            u2[i][j] = u[i][j-1] + u[i-1][j] - time * (u[i][j+1] / u[i+1][j])
    u = deepcopy(u2)

正如预期的那样,这会生成一个新的浮点列表列表。

但是,将其转移到 Numpy,只需:

un = array(u)

然后使用相同类型的循环(这次 u2 是一个零数组):

for time in xrange(start, stop):
    for i in xrange(1,height-1):
        for j in xrange(1, width-1):
            u2[i][j] = un[i][j-1] + un[i-1][j] - time * (un[i][j+1] / un[i+1][j])
    un = u2

... 只要 heightwidth 和时间范围都很小,就会产生与 Python 实现相同的结果,但是随着这些变量设置得更高和更高。

  • 有没有办法防止这种浮动误差的累积?

(这不是真正的代码,只是为了了解 Python 和 Numpy 中如何处理数字,所以关于向量化或其他 Numpy 效率的任何建议都是题外话)

【问题讨论】:

  • 谢谢。但是 Numpy 中的浮点数和纯 Python 中的浮点数之间的差异是否等于其他平台上的浮点数的差异?避免纯 Python 计算结果与 Numpy 计算结果之间不准确的最佳做法是什么?
  • 你能指定python/numpy版本和u2.dtype吗?
  • 2.7.10 和 numpy 1.10.1。 u2.dtype 是 float64。
  • @MathiasEttinger 我不相信这是重复的 - 这个问题是关于在不同机器上运行的相同代码之间的浮点结果差异,而 OP 询问的是两个特定的 Python 和 numpy正在(大概?)在同一台机器上执行的实现。

标签: python numpy floating-point


【解决方案1】:

乍一看问题似乎是un = u2。这会创建对u2 的引用而不是副本,因此您可以在内部循环中直接修改u。这将为您提供与纯 Python 版本不同的结果,因为 u2[i][j] 的值取决于 u[i][j-1]u[i-1][j]

尝试un = u2.copy() 强制复制。

【讨论】:

  • 还是不同的。即使使用矢量化计算也存在不准确性。
  • 你能把你的代码变成一个可重现的例子吗?
  • 将在我回到电脑前发布。另外,在循环体中使用 u2 = u2[i][j] + .... 好吗(或者在循环之后与 un = u2 一样糟糕)?
  • 我猜你的意思是u2[i][j] = u2[i][j-1] + ...?是的,这与在循环外分配 un = u2 一样“糟糕”。在您的 Python 代码中,对于 time 上的每次迭代,u2 中的更新值仅取决于前一个 time 步骤中单独存储在 u 中的“未污染”值。在您的 numpy 代码中,您实际上拥有一个在内部循环中不断更新的数组。
  • 就像 ali_m 说的,你必须输入un = u2.copy() 才能有相同的计算。此外,u[i][j+1] / u[i+1][j] 在第二个循环之后将nan 值放入您的数据中。但是 np.nan==np.nan 被评估为 False ,所以 unu 似乎对于相同的数据是不同的。如果没有具体的数据和不准确的衡量标准,很难说更多。
猜你喜欢
  • 2013-01-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多