#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] с их нормализованными вероятностями.
Но, делая это, вы не соблюдаете плотность вероятности, указанную вами в первую очередь, я не знаю, в каком приложении вы это используете, но это следует учитывать.