【问题标题】:Strange results while using numpy arrays使用 numpy 数组时出现奇怪的结果
【发布时间】:2017-02-19 05:15:54
【问题描述】:

对于某些输入,我得到两个不同的结果,但其他输入却没有。让我用具体的例子来解释。我有以下功能:

In [86]: def f(x, p):
    ...:     n = len(p)
    ...:     tot = 0
    ...:     for i in range(n):
    ...:         tot += p[i] * x**(n-i-1)
    ...:     return tot

p 是一个值非常小的数组:

In [87]: p
Out[87]: 
array([ -3.93107522e-45,   9.17048746e-40,  -8.11593366e-35,
         3.05584286e-30,  -1.06065846e-26,  -3.03946945e-21,
         1.05944707e-16,  -1.56986924e-12,   1.07293061e-08,
        -3.22670121e-05,   1.12072912e-01])

现在考虑输出:

In [90]: [f(i, p) for i in range(11, 20)]
Out[90]: 
[0.11171927108787173,
 0.1116872502272328,
 0.1116552507123586,
 0.11162327253386167,
 0.11159131568235707,
 0.11155938014846242,
 0.1115274659227979,
 0.11149557299598616,
 0.11146370135865244]

In [88]: [f(i, p) for i in np.array(range(11, 20))]
Out[88]: 
[0.11171927108787173,
 0.1116872502272328,
 0.1116552507123586,
 0.11162327253386167,
 0.11159131568235707,
 0.11155938014846242,
 0.1115274659227979,
 0.11149557299598616,
 0.11146370135865244]

如您所见,这些输出与应有的完全相同。唯一的区别是,在一种情况下,我使用range(a, b),而在另一种情况下,我将该范围转换为 numpy 数组。

但是现在,让我们更改范围内的值:

In [91]: [f(i, p) for i in range(50001, 50010)]
Out[91]: 
[-0.011943965521167818,
 -0.011967640114171604,
 -0.011991315947644229,
 -0.012014993019120554,
 -0.012038671327427961,
 -0.012062350870605351,
 -0.012086031644648818,
 -0.012109713648648865,
 -0.012133396879791744]

In [92]: [f(i, p) for i in np.array(range(50001, 50010))]
Out[92]: 
[491.26519430165808,
 491.32457916465478,
 491.38395932037008,
 491.38726606180143,
 491.44663641006275,
 491.50600185375316,
 491.56536239249812,
 491.56864971072332,
 491.6280006336612]

他们甚至没有接近!我错过了一些简单得可笑的东西吗?

【问题讨论】:

  • 这看起来像是一个整数范围问题。在较新的 python 版本中,整数的范围是无限的,你可以通过输入像 10**100-1 这样的荒谬的东西来检查它。 numpy int 是 C 长的,所以它们不提供那种奢侈。

标签: python numpy


【解决方案1】:

您错过了普通 Python 整数是任意精度的事实,而 NumPy 整数是固定大小的。

这个:

x**(n-i-1)

NumPy 输入溢出。

【讨论】:

  • 我明白了。那么有什么补救措施,因为我在实际代码中有 numpy 数组。其实就是熊猫系列。
【解决方案2】:

在错误情况下f(x, p) 中的x 的值是类型numpy.int32。他们可以溢出。这种情况下的修复相对简单,将值转换为int

tot += p[i] * np.asarray(x).astype(int) ** (n - i - 1)

【讨论】:

  • x 作为 numpy 数组传递时,这可能不起作用。对吗?
  • 嗯。但是,在我的情况下它会引发错误:TypeError: only length-1 arrays can be converted to Python scalars
猜你喜欢
  • 1970-01-01
  • 2015-01-18
  • 2018-06-27
  • 2019-09-22
  • 1970-01-01
  • 1970-01-01
  • 2014-03-28
  • 1970-01-01
  • 2021-01-30
相关资源
最近更新 更多