2013-01-23 67 views

回答

8

首先,这里是scipy.nanmean()让我们知道我们正在比较:

def nanmean(x, axis=0): 
    x, axis = _chk_asarray(x,axis) 
    x = x.copy() 
    Norig = x.shape[axis] 
    factor = 1.0-np.sum(np.isnan(x),axis)*1.0/Norig 

    x[np.isnan(x)] = 0 
    return np.mean(x,axis)/factor 

在数学上,这两种方法是等效的。在数字上,它们是不同的。

你的方法涉及单个分割,并且它恰巧:

  • 分子(1. + 2. + 4. + 5.)可以准确地被表示为float;和
  • 分母(4.)是两个幂。

这意味着划分的结果是准确的,3.

stats.nanmean()涉及首先计算平均值[1., 2., 0., 4., 5.],然后调整它以计入NaNs。碰巧,这意味着(2.4)不能完全表示为float,所以从这一点来说,计算是不精确的。

我还没有给它很多想法,但是可能构建一个角色将被颠倒的例子,并且stats.nanmean()会比另一个方法给出更准确的结果。

最让我惊讶的是,stats.nanmean()不是简单地做一些事情,如:

In [6]: np.mean(np.ma.MaskedArray(a, np.isnan(a))) 
Out[6]: 3.0 

在我看来这是一个优越的方法是什么目前并。

+0

确实,'b = np.r_ [1,2,np.nan,4,8.]'对np.mean更友好, 。但我发现很难构建一个反向的例子:) – herrlich10

+1

屏蔽数组很慢(在纯Python中实现),所以我猜测提问者提出了什么('np.nansum(a)/np.sum(〜np.isnan(a )''实际上比'np.mean(np.ma.MaskedArray(a,np.isnan(a))''更快'有人应该试试:) –

+1

所以是的,用一个很长的一维数组'dat', 'np.nansum(dat)/ np.sum(〜np.isnan(dat))'比'np.mean(np.ma.masked_array(dat,np.isnan(dat))''执行速度快10%'。瓶颈的南,,然而,执行10倍的速度。 –

2

答案是在stats.nanmean代码:

x, axis = _chk_asarray(x,axis) 
x = x.copy() 
Norig = x.shape[axis] 
factor = 1.0-np.sum(np.isnan(x),axis)*1.0/Norig 
x[np.isnan(x)] = 0 
return np.mean(x,axis)/factor 

我相信它有事情做与1.0 - np.sum,总和的减法。

+0

谢谢你指出来源。 – herrlich10

1

正如@eumiro提到,stats.nanmean计算出的平均值在从circumlocutions你做

从相同的参考代码的简单一个衬垫的方式方法不同,

np.sum(np.isnan(x),axis)回报numpy.int32这时候乘* 1.0,得到浮点近似值,而不是当结果是整数时导致结果差异的结果

>>> numpy.int32(1)*1.0/5 
0.20000000000000001 
>>> int(numpy.int32(1))*1.0/5 
0.2 
>>> type(np.sum(np.isnan(x),axis)) 
<type 'numpy.int32'> 
+0

我想你指出了另一个有趣的numpy行为:'a = np.int_(1)/5.0; np.float_(a) - > 0.20000000000000001; float(a) - > 0.2' – herrlich10

相关问题