2017-02-19 69 views
0

对于一些输入,我得到了两个不同的结果,但其他输入却没有。让我用具体的例子来解释。我有以下功能:使用numpy阵列时出现奇怪的结果

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] 

而且他们还差得远呢!我错过了一些可笑简单的东西吗?

+1

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

回答

2

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

此:

x**(n-i-1) 

溢出与NumPy的输入。

+0

我明白了。那么补救措施是什么,因为我在实际代码中有numpy数组。实际上,这是一个熊猫系列。 – Peaceful

+0

@Peaceful:使用浮点数。 – user2357112

1

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

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

当'x'作为一个numpy数组传递时,这可能不起作用。对? – Peaceful

+0

嗯。然而,它在我的情况下引发错误:'TypeError:只有长度为1的数组可以转换为Python标量' – Peaceful

+0

谢谢,更新... –