我的阵列操作精度有些问题。我正在进行大量的数组计算,其中必须省略阵列的某些单元格,通过屏蔽完成,或者在这种情况下,通过向数组单元分配非常小的值np.finfo(float).tiny
来省略。<登记/>
但是在数组操作期间,这会导致大约1e-14
的误差,这非常接近机器epsilon。但我仍然不知道错误来自何处以及如何避免错误。由于我执行了数百万次这些操作,因此误差累积到大约2-3%的总误差
这是我最小的工作示例:
arr = np.arange(20).astype(float)
arr[0] = 1e-290
t1 = np.random.rand(20) * 100
t2 = np.random.rand(20) * 100
a = (arr * (t1 - t2)).sum()
b = (arr * (t1 - t2))[1:].sum()
d = (arr * (t1 - t2))[0].sum()
c = b - a
print(c)
# Out[99]: 4.5474735088646412e-13
为避免此问题,我尝试屏蔽arr
:
arr_mask = np.ma.masked_where(arr < 1e-200, arr)
a_mask = (arr_mask * (t1 - t2)).sum()
b_mask = (arr_mask * (t1 - t2))[1:].sum()
c_mask = b_mask - a_mask
print(c_mask)
# Out[118]: 4.5474735088646412e-13
为什么差异c
大于d
的大小,应该是差异?我猜一些机器epsilon问题首先从数组中分配这么小的值?但np.finfo(float).eps
2.2204460492503131e-16
c
仍然比<p:dataGrid
var="citem"
value="#{group.lazyItemGroup}"
paginator="true"
rows="4"
lazy="true"
columns="2"
layout="grid"
id="items"
paginatorTemplate="{CurrentPageReport} {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}"
rowsPerPageTemplate="6,12,16"
>
...
...
...
</p:dataGrid>
小1000倍
我怎么能避免这个?将元素设置为零将不起作用,因为我有很多分歧。在这种情况下,我不能使用掩码有几个原因。但是必须遗漏的细胞的位置永远不会改变。那么我可以以某种方式为这些单元格分配一个“安全”值,以便在改变整个数组操作的结果时将它们排除在外吗?
提前致谢!
答案 0 :(得分:3)
给定浮点类型的粒度不固定,但取决于您开始的值的大小。我鼓励您使用numpy.nextafter
功能:
a = 1.5
>>> np.nextafter(a, -1)
1.4999999999999998
>>> a - np.nextafter(a, -1)
2.220446049250313e-16
>>> a = 1e20
>>> np.nextafter(a, -1)
9.999999999999998e+19
>>> a - np.nextafter(a, -1)
16384.0
这表明通过从a
中减去一些fp数字可以获得的最小正差异取决于a
的大小。
您现在应该能够弄清楚示例中发生的事情