我有以下 Numpy 数组。
a = np.array([0.1, 0.9, 0.17, 0.47, 0.5])
如何找到一个数字,当与数组相乘时,每个元素都变成整数?
例如,在本例中,该数字应为 100,因为
a
乘以 100 将使每个元素都是整数。
>>> a * 100
array([10., 90., 17., 47., 50.])
我尝试过取 10 的最长十进制长度次方。但是,我需要找到尽可能小的数字(并且它必须大于 0)。
b = np.array([1.0, 0.5, 0.25, 0.75, 0.5])
因此,在本例中该数字应为 4 而不是 100。
>>> b * 4
array([4., 2., 1., 3., 2.])
从你的策略开始。获取使数组成为整数的最小 10 次方。然后将其转换为整数并获得公约数。你想要的数字是 10 的幂除以公约数:
b = np.array([1.0, 0.5, 0.25, 0.75, 0.5])
d = np.gcd.reduce((b * 100).astype(int))
这里的d是
25
,你想要的数字是100/25
→4
。
可以使用
import fractions
来扩展接受的答案,以便它包括找到“容差”,即“使数组成为整数的 10 的最小幂”。这使得任意实值浮点数的解决方案变得更加容易。
这是原始示例以及当前接受的答案:
b = np.array([1.0, 0.5, 0.25, 0.75, 0.5])
d = np.gcd.reduce((b * 100).astype(int))
print(100/d, 100/d*b)
输出:
4.0 [4. 2. 1. 3. 2.]
如果不调整 10 的最小幂,则以下示例不适用于当前接受的答案:
b = np.array([1./5, 2./11, 3./15, 4./9, 5./21])
d = np.gcd.reduce((b * 100).astype(int))
print(100/d, 100/d*b)
输出:
100.0 [20. 18.18181818 20. 44.44444444 23.80952381]
但是有了这个解决方案,你不需要先找到 10 的最小幂:
b = np.array([1.0, 0.5, 0.25, 0.75, 0.5])
d = np.lcm.reduce([fractions.Fraction(x).limit_denominator().denominator for x in b])
print(d, d*b)
b = np.array([1./5, 2./11, 3./15, 4./9, 5./21])
d = np.lcm.reduce([fractions.Fraction(x).limit_denominator().denominator for x in b])
print(d, d*b)
它仍然适用于原始示例,输出:
4 [4. 2. 1. 3. 2.]
但它也适用于新示例,输出:
3465 [ 693. 630. 693. 1540. 825.]
正如(Mark Dickinson)对已接受答案的评论中指出的那样here,它可能不适用于分母超过 100 万的分数。