我正试图在数学运算后找到一种方法将数字捕捉或量化为特定值,并且不知道解决问题的最佳方法。
一个具体的例子:
我有一个数字列表,我想成为我的主号码 - 5,10,30,60,120,180
我有一个当前输入的数字列表 - 10,20,60,120
现在我想将所有输入的数字乘以2,然后将它们捕捉(或量化/舍入到)最接近的主数字。
所以一个像10这样的数字,一旦乘以2,我想让它突然变为30.我不认为它是顶部或底部的大问题,因为我认为我可以使用math.ceil和math.floor包含两端。同样地,我希望20也可以舍入为30(20 * 2 = 40,向下舍入为30,接近60)。
我在圆形到10s,100s等方面看到了类似的问题,但无法真正弄清楚如何在那里应用答案,因为我还是比较新的! :)
答案 0 :(得分:2)
对于x
的元素input
,找到x*2
与master
和x*2
的每个元素的绝对差异,然后找到该新列表的最小值将是四舍五入的数字。
代表。对于输入列表中的20,绝对差异列表将是:
[abs(5-40),abs(10-40),abs(30-40),abs(60-40),abs(120-40),abs(180-40)]
导致[35,30,10,20,80,140]
,3rd
元素的最小差异,即30
列表的master
In [14]: inp=[10, 20, 60, 120,17,27,50]
In [15]: master=[5, 10, 30, 60, 120, 180]
In [16]: [min(master,key=lambda y:abs(y-x*2)) for x in inp]
Out[16]: [10, 30, 120, 180, 30, 60, 120]
答案 1 :(得分:2)
使用bisect
模块快速查明所需数量:
import bisect
def quantize(num, quant):
mids = [(quant[i] + quant[i + 1]) / 2.0
for i in xrange(len(quant) - 1)]
ind = bisect.bisect_right(mids, num)
return quant[ind]
quantnum = [5, 10, 30, 60, 120, 180]
inputnum = [10, 20, 60, 120]
for n in inputnum:
print quantize(2 * n, quantnum)
# Output:
#30
#30
#120
#180
中点四舍五入到更大的数量;将bisect_right
更改为bisect_left
以转换为较小的一个。
为简单起见,此实现在每次调用时都会重新创建mids
列表。一个有效的实现将重用中点,并将以O(log n)
最坏情况的复杂性运行。