Разрешить ValueError при использовании случайного выбора из списка с ограничениями
Задан случайный список и список ограничений:
>>> import numpy as np
>>> x = np.random.randint(0, 50, 10)
>>> x
array([27, 14, 42, 1, 9, 43, 16, 39, 27, 3])
>>> y = [1,2,5, 19, 27]
>>> n = 5
И я хочу выборку (без замены) N из X без значений в Y, я мог бы сделать что-то вроде этого:
>>> np.random.choice(list(set(x).difference(y)), n, replace=False)
array([39, 9, 43, 14, 16])
N-это пользовательский ввод, который, безусловно, меньше, чем len(x)
, но учитывая, что я понятия не имею, больше Ли N, чем подмножество X-Y, я мог бы получить эту ситуацию, которая бросает ValueError
:
>>> np.random.choice(list(set(x).difference(y)), 8, replace=False)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "mtrand.pyx", line 1150, in mtrand.RandomState.choice (numpy/random/mtrand/mtrand.c:18113)
ValueError: Cannot take a larger sample than population when 'replace=False'
Учитывая, что я должен был бы задать максимальное значение для N, например:
>>> n = min(n, len(list(set(x).difference(y))) )
>>> n
7
Но в этом случае N больше не 8, который вводит пользователь:
>>> np.random.choice(list(set(x).difference(y)), n, replace=False)
array([14, 39, 43, 3, 42, 9, 16])
Поэтому я должен пост-добавить вывод:
>>> list(np.random.choice(list(set(x).difference(y)), _n, replace=False)) + [-1]*(n-_n)
[43, 42, 9, 16, 3, 39, 14, -1]
Чтобы подвести итог, я должен попробовать N no. элементов без замены из подмножества значений X, которое не находится в Y, и мне нужно заполнить "пробелы" с -1, если длина подмножества меньше N.
Я мог бы сделать это с помощью кода выше, но есть ли менее подробный (надеюсь, также более эффективный) способ добиться того же результата?
1 ответ:
Я бы, вероятно, использовал
np.in1d
чтобы взять разницу, а затемnp.append
для последующей обработки:x = np.random.randint(0, 50, 10) y = [1, 2, 5, 19, 27] n = 12 x_y = x[~np.in1d(x,y)] arr = np.append(np.random.choice(x_y, len(x_y), replace=False), [-1]*(n-len(x_y))) print arr # array([35, 46, 39, 21, 9, 37, 17, 23, 8, -1, -1, -1])
Если
n
меньше длины разности, то ничего не добавляется.