【发布时间】:2016-01-28 08:37:12
【问题描述】:
这是我前几天试图解决的一个有趣的问题。是否可以强制一个float 的有效数字或指数与Python 中的另一个float 相同?
出现问题是因为我试图重新调整一些数据,以便最小值和最大值与另一个数据集匹配。但是,我重新调整后的数据略有偏差(大约小数点后 6 位),这足以导致问题。
给出一个想法,我有f1 和f2 (type(f1) == type(f2) == numpy.ndarray)。我想要np.max(f1) == np.max(f2) and np.min(f1) == np.min(f2)。为此,我这样做:
import numpy as np
f2 = (f2-np.min(f2))/(np.max(f2)-np.min(f2)) # f2 is now between 0.0 and 1.0
f2 = f2*(np.max(f1)-np.min(f1)) + np.min(f1) # f2 is now between min(f1) and max(f1)
结果(仅作为示例)将是:
np.max(f1) # 5.0230593
np.max(f2) # 5.0230602 but I need 5.0230593
我最初的想法是强制float 的指数是正确的解决方案。我找不到太多关于它的内容,所以我根据需要做了一个解决方法:
exp = 0
mm = np.max(f1)
# find where the decimal is
while int(10**exp*mm) == 0
exp += 1
# add 4 digits of precision
exp += 4
scale = 10**exp
f2 = np.round(f2*scale)/scale
f1 = np.round(f1*scale)/scale
现在np.max(f2) == np.max(f1)
但是,有没有更好的方法?我做错什么了吗?是否可以将float 重塑为与另一个float 相似(指数或其他方式)?
编辑:正如建议的那样,我现在正在使用:
scale = 10**(-np.floor(np.log10(np.max(f1))) + 4)
虽然我上面的解决方案可以工作(对于我的应用程序),但我很想知道是否有一种解决方案可以以某种方式强制float 具有相同的指数和/或有效数字,以便数字变得相同。
【问题讨论】:
-
根据您正在使用的范围,您也许可以使用
np.log10(x)来解决问题。使用一些虚拟值,我得到 `np.log10(1.2312412) = 0.090343139501527295` 和np.log10(12.312412) = 1.0903431395015273,但np.log10(.12312412) = -0.90965686049847261 -
或者,只要您仅按 10 的幂进行缩放
10**(np.log10(1.2312412)) = 1.2312411999999999、10**(np.log10(1.2312412)+2) = 123.12412000000005和10**(np.log10(1.2312412)-2) = 0.012312411999999998,这意味着尾数中的错误被推到最后一位。跨度> -
啊,好吧。 FWIW,“尾数”的浮点使用往往不受欢迎,因为它与尾数作为(以 10 为底)对数的小数部分的旧数学定义相冲突。请改用“有效数字”。
-
回复
f2 *= (np.max(f1)-np.min(f1)) + np.min(f1)。这不应该是f2 = f2 * (np.max(f1)-np.min(f1)) + np.min(f1)。 IE。您想按f1的范围重新缩放,然后添加f1的最小值。在我看来,就目前而言,您将 0 到 1 范围乘以*=右侧的整个术语。 -
@TooTone:很可能是单精度算术(即 dtype
float32的 NumPy 数组)。
标签: python numpy floating-point floating-accuracy