我正在使用numpy的random.choise来获取范围(0,1000)内的n个整数,其中相同的整数不能被选择两次(replace = false)。
但是由于每个整数都是具有一定长度(例如 - 10)的子列表的起点,因此我希望随机函数不从已选择的整数中选择任何其他 +- 10 的整数。
使用 p= 参数是不可能的,因为我事先不知道将选择哪个 n。 (可以使用循环 - 每次迭代都会将新选择的整数中的 +-10 个整数添加到分配概率为 0 的概率列表中,但这在我看来不是最佳解决方案......)
例如:
myseries = list(range(1000))
n = 30
blockRange = 10
np.random.choice(myseries, n, replace=False)
这会返回 30 个数字,其中两个是 33 和 37 - 但我想“禁止”这个(如果存在 33,则不应允许 24 到 42 之间的数字!)
谢谢
一个解决方案是迭代地构建它,它肯定会比 numpy 方法慢,但我找不到一种方法来使用 numpy 进行特定的随机分布。
我创建了一个
res
列表和一个 forbidden
集。
我迭代
n
次(这里是n=30
),尝试计算特定范围内的随机数。如果不是 forbidden,意味着该号码不在 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)))
一个技巧可能是在数字之间生成随机空间并将其标准化以保持在给定范围内。对距离求和以获得索引
这是我使用的代码:
def space_random_opt(n, lower_bound, upper_bound, space):
range_n = upper_bound-lower_bound
assert range_n >=space*n, "sample too tiny" #check if sample is large enough
coeffs = np.random.rand(n) #generate coefficients of spacing
spacer = (range_n-n*space)/np.sum(coeffs) #normalize coeffs
spacerz = (spacer*coeffs)+space #get distances
idx = np.cumsum(spacerz).astype(int) #get indices
return idx