Python numpy数组和中的不理解

Python numpy数组和中的不理解,python,arrays,numpy,Python,Arrays,Numpy,T1和P1是两个numpy数组,分别包含温度(以开尔文表示,介于100和250之间)和压力(以帕斯卡表示,介于700和1之间)。它们的形状完全相同432*45*135*135这些数组的每个元素都是numpy.float32。这是我的密码: 1 T2=T1+1. 2 P2=P1+1. 3 print np.sum(np.square(np.subtract(T2,T1))) 4 print np.sum(np.square(np.subtract(P2,P1))) 5 print (

T1
P1
是两个numpy数组,分别包含温度(以开尔文表示,介于100和250之间)和压力(以帕斯卡表示,介于700和1之间)。它们的形状完全相同
432*45*135*135
这些数组的每个元素都是
numpy.float32
。这是我的密码:

1  T2=T1+1.
2  P2=P1+1.

3  print np.sum(np.square(np.subtract(T2,T1)))
4  print np.sum(np.square(np.subtract(P2,P1)))

5  print ((T2-T1)-1.<1e-3).sum()
6  print ((P2-P1)-1.<1e-3).sum()
我不明白为什么:

  • 说明3和说明4给出的结果不同,因为
    T2-T1
    P2-P1
    都应等于一个
    432*45*135*135
    满1的数组
  • 指令3和4都没有给出好的结果,这是由指令5和6给出的,并且等于数组中的元素数(
    432*45*135*135=354294000
  • T2-T1
    P2-P1
    中的某些元素不等于1,如果我提高指令5和6中的比较精度,可以看出这一点
表情

print ((T2-T1)-1.<1e-5).sum()
print ((P2-P1)-1.<1e-5).sum()
我可以想象这些问题与精度有关,但我不应该使用dtype
numpy.float32
遇到这个问题。我试过:

T2=T1+np.float32(1.)
P2=P1+np.float32(1.)

这不会改变任何事情。有什么想法吗?谢谢,计算大量数字的总和是一个棘手的问题,因为计算机可能无法以足够的精度来表示数字

32位浮点只有大约7位精度。因此,如果将一个小数字与一个大数字相加,并且它们之间的比率大于
2^24
(≈
1.7*10^7
)那么结果可能就是这么大的数字。所以当求和时,一旦你的和达到这个值,加+1将不再改变和


您可能只需要使用双精度就可以了(但是结果仍然会有相当大的错误,因为值的数量太多)。否则,您将不得不使用像Kahan求和这样的算法,或者,如果没有负数,则分阶段进行求和。例如,您可以先计算每行432个数字的总和,然后计算列中45行的总和,等等。

在@roeland行之后,此代码实现了以下功能:

T1=T1.astype(np.float64)
T2=T1+np.float64(1.)
P1=P1.astype(np.float64)
P2=P1+np.float64(1.)

print np.sqrt(np.sum(np.square(np.subtract(T2,T1))))
print np.sqrt(np.sum(np.square(np.subtract(P2,P1))))
提供正确的输出:

354293978
354041812
354294000.0
354294000.0

谢谢你,罗兰。我理解你的观点,但我不认为在这种情况下,在每种情况下都会找到相同的值(1.7*10^7),对应于极限吗?@ArnaudPROST不确定,我认为这取决于数组中的精确值(它们不完全是1.0),以及这些中间结果的舍入方式。您可以通过将所有元素初始化为1.0的数组求和来进行测试。如果我创建一个数组
test=np.zero([432,45135135])
,然后执行
test=test+1.0
print test.sum()
我获得了我解释为您所说的限制的
1.67772e+07
,在此基础上,添加1不会再改变任何事情。但我仍然不明白我们如何使用压力阵列进行检查,达到
2.24963e+07
可能后一个阵列的元素略大于1.0
354294000.0
354294000.0