简体   繁体   English

numpy.random 生成的替代方案,具有选择值和特定值的频率

[英]Alternatives for numpy.random generation with choice values and specific frequency of values

I am working in generating an (1109, 8) array with random values generated from a fixed set of numbers [18, 24, 36, 0], I need to ensure each row contains 5 zeros at all times, but it wasn't happening even after adjusting the weightings for probabilities.我正在生成一个 (1109, 8) 数组,该数组具有从一组固定数字 [18, 24, 36, 0] 生成的随机值,我需要确保每行始终包含 5 个零,但事实并非如此即使在调整了概率的权重之后也会发生。

My workaround code is below but wanted to know if there is an easier way with another function?我的解决方法代码如下,但想知道另一个 function 是否有更简单的方法? or perhaps by adjusting some of the parameters of the generator?或者也许通过调整生成器的一些参数?https://numpy.org/doc/stable/reference/random/generator.htmlhttps://numpy.org/doc/stable/reference/random/generator.html

#Random output using new method
from numpy.random import default_rng
rng = default_rng(1)

#generate an array with random values of test duration,
test_duration = rng.choice([18, 24, 36, 0], size = arr.shape, p=[0.075, 0.1, 0.2, 0.625])
# ensure number of tests equals n_tests
n_tests = 3
non_tested = arr.shape[1] - n_tests


for row in range(len(test_duration)):
    while np.count_nonzero(test_duration[row, :]) != n_tests:
        new_test = rng.choice([18, 24, 36, 0], size = arr.shape[1], p=[0.075, 0.1, 0.2, 0.625])
        test_duration[row, :] = np.array(new_test)
    else:
        pass
print('There are no days exceeding n_tests')
#print(test_durations)
print(test_duration[:10, :])

If you need 5 zeros in every row, you can just randomly select 3 values from [18, 24, 36] , pad the rest with zeros and then do a per-row random shuffle.如果每行需要 5 个零,则可以从[18, 24, 36]中随机 select 3 个值,用零填充 rest,然后进行每行随机洗牌。 The numpy shuffle happens in-place, so you don't need to reassign. numpy shuffle 就地发生,因此您无需重新分配。

import numpy as np

c = [18,24,26]

p = np.array([0.075, 0.1, 0.2])
p = p / p.sum()  # normalize the probs

a = np.random.choice(c, size=(1109, 3), replace=True, p=(p/p.sum()))
a = np.hstack([a, np.zeros((1109, 5), dtype=np.int32)])

list(map(np.random.shuffle, a))

a
# returns:
array([[ 0,  0,  0,  0, 36,  0, 36, 36],
       [ 0, 36,  0, 24, 24,  0,  0,  0],
       [ 0,  0,  0,  0, 36, 36, 36,  0]])
       ...
       [ 0,  0,  0, 24, 24, 36,  0,  0],
       [ 0, 24,  0,  0,  0, 36,  0, 18],
       [ 0,  0,  0, 36, 36, 24,  0,  0]])

You could simply create a random choice for the 5 positions of the zeros in the array, this way you would enforce that there are indeed 5 zeros, and after you sample the [18, 24, 36] with their normalized probabilities.您可以简单地为数组中零的 5 个位置创建一个随机选择,这样您就可以强制确实存在 5 个零,并且在您对 [18,24,36] 及其归一化概率进行采样之后。

But by doing this you are not respecting the probability density that you specified in the first place, I don't know in which application you're using this for but this is a point to consider.但是这样做你不尊重你首先指定的概率密度,我不知道你在哪个应用程序中使用它,但这是需要考虑的一点。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM