如果您需要保证唯一性,同时也更高效的话,可以尝试以下方法:
- 尝试一次性生成
n
个在 [lo, hi]
范围内的随机浮点数。
- 如果唯一的浮点数长度不是
n
,则尝试生成所需数量的浮点数
然后继续执行,直到足够为止,而不是通过 Python 级别循环逐个检查集合来生成它们。
如果您能承担 NumPy 的话,使用
np.random.uniform
可以大大提高速度。
import numpy as np
def gen_uniq_floats(lo, hi, n):
out = np.empty(n)
needed = n
while needed != 0:
arr = np.random.uniform(lo, hi, needed)
uniqs = np.setdiff1d(np.unique(arr), out[:n-needed])
out[n-needed: n-needed+uniqs.size] = uniqs
needed -= uniqs.size
np.random.shuffle(out)
return out.tolist()
如果您无法使用NumPy,根据您的数据需求,应用检查重复项的相同概念并维护一个集合仍然可能更有效。
def no_depend_gen_uniq_floats(lo, hi, n):
seen = set()
needed = n
while needed != 0:
uniqs = {random.uniform(lo, hi) for _ in range(needed)}
seen.update(uniqs)
needed -= len(uniqs)
return list(seen)
大致基准测试
极端退化情况
%timeit gen_uniq_floats(0, 2**-50, 1000)
<b>153 µs ± 3.71 µs per loop</b> (mean ± std. dev. of 7 runs, 10000 loops each)
%timeit no_depend_gen_uniq_floats(0, 2**-50, 1000)
<b>495 µs ± 43.9 µs per loop</b> (mean ± std. dev. of 7 runs, 1000 loops each)
%timeit sample_floats(0, 2**-50, 1000)
<b>618 µs ± 13 µs per loop</b> (mean ± std. dev. of 7 runs, 1000 loops each)
更“平常”的情况(包含更多样本)
%timeit gen_uniq_floats(0, 1, 10**5)
<b>15.6 ms ± 1.12 ms per loop</b> (mean ± std. dev. of 7 runs, 100 loops each)
%timeit no_depend_gen_uniq_floats(0, 1, 10**5)
<b>65.7 ms ± 2.31 ms per loop</b> (mean ± std. dev. of 7 runs, 10 loops each)
%timeit sample_floats(0, 1, 10**5)
<b>78.8 ms ± 4.22 ms per loop</b> (mean ± std. dev. of 7 runs, 10 loops each)