如何在 Python 中生成唯一随机浮点列表

2024-04-24

我知道有一些简单的方法可以生成唯一随机整数的列表(例如random.sample(range(1, 100), 10)).

我想知道除了编写一个像范围一样但接受这样的浮点数的函数之外,是否有更好的方法来生成唯一随机浮点数的列表:

import random

def float_range(start, stop, step):
    vals = []
    i = 0
    current_val = start
    while current_val < stop:
        vals.append(current_val)
        i += 1
        current_val = start + i * step
    return vals

unique_floats = random.sample(float_range(0, 2, 0.2), 3)

有一个更好的方法吗?


Answer

一种简单的方法是保留一组迄今为止看到的所有随机值,并在出现重复时重新选择:

import random

def sample_floats(low, high, k=1):
    """ Return a k-length list of unique random floats
        in the range of low <= x <= high
    """
    result = []
    seen = set()
    for i in range(k):
        x = random.uniform(low, high)
        while x in seen:
            x = random.uniform(low, high)
        seen.add(x)
        result.append(x)
    return result

Notes

  • 这个技术是Python自己的随机抽样()已实施。

  • 该函数使用一个set https://docs.python.org/3/library/stdtypes.html#set-types-set-frozenset跟踪先前的选择,因为搜索集合的时间复杂度为 O(1),而搜索列表的时间复杂度为 O(n)。

  • 计算重复选择的概率相当于著名的生日问题 https://en.wikipedia.org/wiki/Birthday_problem.

  • 给定 2**53 个不同的可能值random(),重复的情况很少见。 平均而言,您预计会出现大约 120,000,000 个样本的重复浮点数。

变体:有限的浮动范围

如果人口仅限于一系列均匀分布的浮点数,那么可以使用随机抽样() https://docs.python.org/2.7/library/random.html#random.sample直接地。唯一的要求是人口必须是Sequence https://docs.python.org/2.7/glossary.html#term-sequence:

from __future__ import division
from collections import Sequence

class FRange(Sequence):
    """ Lazily evaluated floating point range of evenly spaced floats
        (inclusive at both ends)

        >>> list(FRange(low=10, high=20, num_points=5))
        [10.0, 12.5, 15.0, 17.5, 20.0]

    """
    def __init__(self, low, high, num_points):
        self.low = low
        self.high = high
        self.num_points = num_points

    def __len__(self):
        return self.num_points

    def __getitem__(self, index):
        if index < 0:
            index += len(self)
        if index < 0 or index >= len(self):
            raise IndexError('Out of range')
        p = index / (self.num_points - 1)
        return self.low * (1.0 - p) + self.high * p

下面是从 10.0 到 20.0 的 41 个均匀间隔的浮点数范围中无放回地选择 10 个随机样本的示例。

>>> import random
>>> random.sample(FRange(low=10.0, high=20.0, num_points=41), k=10)
[13.25, 12.0, 15.25, 18.5, 19.75, 12.25, 15.75, 18.75, 13.0, 17.75]
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在 Python 中生成唯一随机浮点列表 的相关文章

随机推荐