Из 2D-массива создайте 2-й 2D-массив уникальных (неповторяющихся) случайных выбранных значений из 1-го массива (значения, не разделяемые между строками) без использования цикла - PullRequest
0 голосов
/ 31 декабря 2018

Это продолжение этого вопроса.

Из 2-мерного массива создайте еще один 2-мерный массив, состоящий из случайно выбранных значений из исходного массива (значения не разделяются между строками) без использования цикла

Я ищуспособ создания двумерного массива, строки которого являются случайно выбранными уникальными значениями (неповторяющимися) из другой строки, без использования цикла.

Вот способ сделать это с помощью цикла.

pool =  np.random.randint(0, 30, size=[4,5])
seln = np.empty([4,3], int)

for i in range(0, pool.shape[0]):
    seln[i] =np.random.choice(pool[i], 3, replace=False) 

print('pool = ', pool)
print('seln = ', seln)

>pool =  [[ 1 11 29  4 13]
 [29  1  2  3 24]
 [ 0 25 17  2 14]
 [20 22 18  9 29]]
seln =  [[ 8 12  0]
 [ 4 19 13]
 [ 8 15 24]
 [12 12 19]]

Вот метод, который не использует цикл, однако он может выбрать одно и то же значение несколько раз в каждой строке.

pool =  np.random.randint(0, 30, size=[4,5])
print(pool)
array([[ 4, 18,  0, 15,  9],
       [ 0,  9, 21, 26,  9],
       [16, 28, 11, 19, 24],
       [20,  6, 13,  2, 27]])

# New array shape
new_shape = (pool.shape[0],3)

# Indices where to randomly choose from
ix = np.random.choice(pool.shape[1], new_shape)
array([[0, 3, 3],
       [1, 1, 4],
       [2, 4, 4],
       [1, 2, 1]])

ixs = (ix.T + range(0,np.prod(pool.shape),pool.shape[1])).T
array([[ 0,  3,  3],
       [ 6,  6,  9],
       [12, 14, 14],
       [16, 17, 16]])

pool.flatten()[ixs].reshape(new_shape)
array([[ 4, 15, 15],
       [ 9,  9,  9],
       [11, 24, 24],
       [ 6, 13,  6]]) 

Я ищу метод, который не использует цикл, и если выбрано определенное значение из строки, это значение не может быть выбрано снова.

1 Ответ

0 голосов
/ 01 января 2019

Вот способ без явного зацикливания.Однако это требует генерации массива случайных чисел размера исходного массива.Тем не менее, генерация выполняется с использованием скомпилированного кода, поэтому он должен быть довольно быстрым.Он может потерпеть неудачу, если вам случится сгенерировать два одинаковых числа, но вероятность того, что это произойдет, практически равна нулю.

m,n = 4,5 
pool =  np.random.randint(0, 30, size=[m,n])

new_width = 3
mask = np.argsort(np.random.rand(m,n))<new_width

pool[mask].reshape(m,3)

Как это работает: Мы генерируем случайный массив чисел с плавающей точкой, иаргументируй это.По умолчанию, когда artsort применяется к 2d-массиву, он применяется вдоль оси 1, поэтому значение записи i,j в списке с сортировкой соответствует тому, что помещает j -ую запись i -ой строкипоявится, если вы отсортируете i -ю строку.

Затем мы найдем все значения в этом массиве, где записи, значения которых меньше new_width.Каждая строка содержит числа 0,...,n-1 в случайном порядке, поэтому ровно new_width из них будет меньше new_width.Это означает, что каждая строка mask будет иметь ровно new_width количество записей, равных True, а остальные будут False (когда вы используете логический оператор между ndarray и скаляром, он применяет его по компонентам).

Наконец, логическая маска применяется к исходным данным, чтобы получить new_width много записей из каждой строки.

Вы также можете использовать np.vectorize для вашего решения цикла, хотя этоэто просто сокращение для цикла.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...