小编典典

在一个范围内生成均匀分布的倍数/样本

python

问题
I的 特定实例 的int范围是1-100。我想在此范围内生成n个总数,这些总数应 尽可能均匀地分布, 并包括第一个和最后一个值。

start = 1, end = 100, n = 5   
Output: [1, 25, 50, 75, 100]

start = 1, end = 100, n = 4   
Output: [1, 33, 66, 100]

start = 1, end = 100, n = 2   
Output: [1, 100]

我目前所拥有的
实际上是一种可行的方法,但是我一直觉得自己在想这个问题,而错过了一些更简单的方法?这是最有效的方法还是可以改进?

def steps(start, end, n):
    n = min(end, max(n, 2) - 1)
    mult = end / float(n)
    yield start
    for scale in xrange(1, n+1):
        val = int(mult * scale)
        if val != start:
            yield val

请注意,我确保此函数将始终至少返回范围的下限值和上限值。所以,我强迫n >= 2

仅作为搜索参考,我正在使用它来从渲染的序列中采样图像帧,通常在该序列中需要第一个,中间,最后一个。但是我希望能够更好地缩放以处理非常长的图像序列并获得更好的覆盖范围。

解决:从选定的答案

我最终使用了@vartec的答案的这个经过稍微修改的版本,作为生成器,并且还设置n了安全性上限:

def steps(start,end,n):
    n = min(end, max(n, 2))
    step = (end-start)/float(n-1)
    return (int(round(start+x*step)) for x in xrange(n))

阅读 302

收藏
2021-01-20

共1个答案

小编典典

您需要适当的舍入:

def steps(start,end,n):
    if n<2:
        raise Exception("behaviour not defined for n<2")
    step = (end-start)/float(n-1)
    return [int(round(start+x*step)) for x in range(n)]
2021-01-20