Альтернативы для numpy.случайная генерация с выбранными значениями и определенной частотой значений

#python #numpy #random

#python #numpy #Случайный

Вопрос:

Я работаю над созданием массива (1109, 8) со случайными значениями, сгенерированными из фиксированного набора чисел [18, 24, 36, 0], Мне нужно убедиться, что каждая строка всегда содержит 5 нулей, но этого не произошло даже после корректировки весов для вероятностей.

Мой обходной код приведен ниже, но хотелось бы знать, есть ли более простой способ с другой функцией? или, возможно, путем настройки некоторых параметров генератора? https://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, :])
 

Ответ №1:

Если вам нужно 5 нулей в каждой строке, вы можете просто случайным образом выбрать 3 значения [18, 24, 36] , дополнить остальные нулями, а затем выполнить случайную перетасовку для каждой строки. Перетасовка numpy происходит на месте, поэтому вам не нужно переназначать.

 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]])
 

Комментарии:

1. Отличная идея. Ваш код просто отсутствует c=[18,24,26] ; и, возможно, можно упомянуть, что list(map(...) это делает то же for row in a: np.random.shuffle(row) самое, что и .

Ответ №2:

Вы могли бы просто создать случайный выбор для 5 позиций нулей в массиве, таким образом, вы обеспечили бы, чтобы действительно было 5 нулей, и после выборки [18, 24, 36] с их нормализованными вероятностями.

Но, делая это, вы не соблюдаете плотность вероятности, указанную вами в первую очередь, я не знаю, в каком приложении вы это используете, но это следует учитывать.