【问题标题】:numpy random.choise - get several values with a minimum distance between themnumpy random.choice - 获取多个值之间的最小距离
【发布时间】:2022-08-03 17:50:42
【问题描述】:

我正在使用 numpy 的random.choise 来获取范围(0,1000)内的 n 个整数,其中不能选择两次相同的整数(替换 = 假)。

但是由于每个整数都是具有一定长度(例如- 10)的子列表的起点,我希望随机函数不从已经选择的整数中选择任何其他整数 +- 10。

使用 p= 参数是不可能的,因为我事先不知道将选择哪个 n\'s。 (可以使用一个循环 - 每次迭代都将新选择的整数中的 +-10 个整数添加到分配概率为 0 的概率列表中,但在我看来,这不是最佳解决方案......)

例如:

myseries = list(range(1000))
n = 30 
blockRange = 10
np.random.choice(myseries, n, replace=False)

这将返回 30 个数字,其中两个是 33 和 37 - 但我想“禁止”这个(如果有 33,则不应允许 24 到 42 之间的数字!)

谢谢

    标签: python numpy random combinations probability


    【解决方案1】:

    一种解决方案是迭代地构建它,它肯定会比 numpy 方法慢,但我找不到用 numpy 进行特定随机分布的方法。

    我创建了一个res 列表和一个forbidden 集合。

    我迭代n 次(这里是n=30),尝试计算特定范围内的随机数。如果不是禁止的,这意味着这个数字不在forbidden 集合中,我可以将它添加到我的res 列表中。

    我还添加到我的forbidden 设置每个int 在这个范围内:[rand_num-9; rand_numb[

    但如果它在我的forbidden 集合中,我会通过while 循环重试以找到合适的随机数。

    代码 :

    import random 
    
    n, lower_bound, upper_bound = 30, 0, 1000
    res = []
    forbidden = set()
    for _ in range(n):
        rand_numb = random.randint(lower_bound, upper_bound)
        while rand_numb in forbidden:
            rand_numb = random.randint(0,1000)
        res.append(rand_numb)
        forbidden = forbidden.union(set(range(rand_numb-9, rand_numb+10)))
    

    【讨论】:

    • 谢谢,它运作良好。因为它是一个长数组(即在我的实际情况下,'upper_bound' 值比 1000 高),它需要非常慢才能运行(每次检查 rand_numb 是否已经在禁止的数字中......所以我想改变这个逻辑并对每个禁止值执行 list.remove ,以便在下一次迭代中数组会更短。不幸的是,对许多值迭代运行 list.remove(i) 也非常慢(但也许我只是在做它不是最佳的...). 以防万一它与其他人相关 - 你可以考虑改变它。
    • 实际上检查一个 rand_numb 是否被禁止并不慢,这就是我使用集合(HashMap)的原因,因为检查一个值是否包含在一个 set() 中非常快(你不会遍历每个值直到你找到它)。我认为您可以更快地做一些事情,但是很难解释和编码……让我考虑一下
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多