找到公共乘数器以将小数数组转换为尽可能接近整数

Find common multipler to convert array of decimals as close as possible to a whole number

提问人:MC Jong 提问时间:11/1/2023 更新时间:11/4/2023 访问量:56

问:

我有一个长度约为 10 的 numpy 权重数组:

weight_np = [1.56789, 2.1234, ...]

我需要找到一个通用的乘数器,它将所有权重转换为整数(或尽可能接近)。我知道如果您希望所有数组输入都是整数,您可以使用 GCD 找到一个公共倍数器,但我不确定如何解决这个问题,您是否允许 +- 0.1 的“误差”范围?

我可以使用任何算法来做到这一点吗?

python 数组 数学

评论

0赞 Mark Ransom 11/1/2023
总是可以将它们全部转换为精确整数,只需将每个乘以 2**53!
0赞 Mark Ransom 11/1/2023
你可以忽略我上面的翻转评论,它不适用于非常接近零的数字。但这个想法仍然存在,浮点数组合在一起的方式总是可以从中得到一个精确的整数。
0赞 Thierry Lathuille 11/1/2023
“+- 0.1 的'误差'边际”是什么意思?0.1 %,或者究竟是什么?
0赞 chux - Reinstate Monica 11/1/2023
@MC Jong,如果值为 [1.56789e100, 2.1234e100, ...],则 GCD 可能非常大。你也想要吗?
0赞 Simon Goater 11/2/2023
如果将一个元素乘以一个数字数组,那么可以假设,平均而言,这些值中有五分之一的小数点在 .9 和 .1 之间。如果对 2 个元素执行相同的操作,则 5^2=25 中大约有 1 个元素的小数点在 .9 和 .1 之间。如果你有 10,那么它是 5^10 = 9765625。你可以用蛮力破解。

答:

0赞 Mark Ransom 11/4/2023 #1

您可以按照评论中提到的使用蛮力。如果你不需要最小乘数,这实际上很容易。

def near_int(nparr):
    multiplier = 1
    while True:
        scaled = nparr * multiplier
        rounded = np.rint(scaled)
        if np.allclose(scaled, rounded, atol=0.100000000001, rtol=0):
            return multiplier, scaled
        multiplier *= 10

weight_np = np.array([1.56789, 2.1234, 3.14, 9.11])
near_int(weight_np)
(10000, array([15678.9, 21234. , 31400. , 91100. ]))

容差仅略高于 0.1,以允许浮点不准确性。

我采用了一种策略,将乘数保持在 10 的幂,因为这样可以得到更容易理解的结果。但是您可以使用您想要的任何其他方法。