【问题标题】:Numpy sum function returns 1.67772e+07Numpy sum 函数返回 1.67772e+07
【发布时间】:2015-06-19 16:40:27
【问题描述】:

我有两个大 (432*136*136*46) 'numpy.ndarray' H1 和 H2,其中包含对应于两个模拟的高度值。我想在 H1 和 H2 具有相同的高度时生成一个数组,当它们不具有相同的高度时生成 0。然后,我想知道我选择了多少个元素,所以我想计算这个矩阵的元素之和。这是我的代码:

H1=np.concatenate([np.around(files1[i].hrtm()[:,0:45,:,:]/h) for i in range(0,files1.__len__())])
H2=np.concatenate([np.around(files2[i].hrtm()[:,0:45,:,:]/h) for i in range(0,files2.__len__())])

diff=np.absolute(H1-H2)
diff[diff==0.]=np.float64(-1.)
diff[diff!=-1]=np.float64(0.)
diff=diff*diff

print np.sum(diff)

这是我的输出,它总是一样的,不依赖于数据:

1.67772e+07

经过一些研究,我了解到它与浮点数的最大大小有关。我尝试了几种格式,将 np.float64 替换为 int、float、np.float32 或什么都没有,它们都给出了相同的结果。

你知道我怎样才能得到实数吗?

【问题讨论】:

  • 跟单精度浮点数的精度有关:在值2^24以上,加1没有任何作用,因为被吸收了。
  • @rth:这是一个奇怪的断言。 diff == 0. 将给出一个数组,该数组在对应于零的位置包含 Trues,在其他位置包含 Falses。它会按照 OP 的意图工作。
  • @MarkDickinson 注意,“如果diff 是一个浮点数组”在我的评论中。我错过了使用np.around 将其转换为整数的事实。否则,您可能会遇到舍入问题,例如在 python 中检查 2.2 * 3.0 == 6.6 的结果为 False
  • @rth:是的,当然你必须小心舍入问题。但是说diff == 0. 不会匹配零是完全错误的,即使diff 具有浮点类型。 (顺便说一句,它在这里,因为 np.around 返回浮点 dtype 的东西。)0.0 == 0.0True
  • 是的。我说的是一般原则:测试float1==float2 是否只是在找麻烦,即使它可能在 95% 的情况下都有效。

标签: python arrays numpy floating-point floating-point-precision


【解决方案1】:

您的diff-array 的类型是H1H2 的类型。由于您只添加了许多1s,您可以将diff 转换为bool

print diff.astype(bool).sum()

或者更简单

print (H1 == H2).sum()

但由于浮点值并不精确,因此可能会测试非常小的差异:

print (abs(H1 - H2) < 1e-30).sum()

【讨论】:

  • 效果很好,非常感谢,这些解决方案更加优雅。
  • 请注意,H1H2 的值已经四舍五入到最接近的整数,因此在这里使用容差并不能实现任何效果。 (例如,如果这些是以英尺为单位的高度,那么 1e-30 将太小而无用:比较本质上是比较是否相等。)
  • @MarkDickinson:所以我忽略了舍入,仍然数字公差与物理公差无关。
  • 使用公差的问题是为该公差选择一个有用的值。 1e-30 将非常小(从数字的角度来看,而不是物理的):单精度浮点数大约有 7 个十进制数字精度,因此任何两个大于 1e-22 的不相等浮点数将相差超过1e-30。这使得容差测试等效于大于1e-22 的值的相等性测试。鉴于它们是高度,我认为我们可以有把握地假设这些数字大于1e-22
猜你喜欢
  • 1970-01-01
  • 2016-05-27
  • 1970-01-01
  • 2017-08-24
  • 1970-01-01
  • 2014-04-20
  • 1970-01-01
  • 1970-01-01
  • 2017-07-30
相关资源
最近更新 更多