Разрешить 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 2

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 меньше длины разности, то ничего не добавляется.