Numpy: случайное подмножество элементов - PullRequest
0 голосов
/ 26 апреля 2018

У меня есть двумерный массив numpy, интерпретирующий его как сетку, и я хочу переставить подмножество элементов. Точнее, край должен быть сопоставлен с краем, а угол - с углом.

  • np.random.shuffle делает работу, когда любая перестановка элементов в порядке.

Я могу получить доступ к углам:

a = np.arange(16).reshape((4,4))
a[[0,0,-1,-1],[0,-1,0,-1]]

Однако, когда я звоню

np.random.shuffle(a[[0,0,-1,-1],[0,-1,0,-1]])

массив не изменен. Чтение https://docs.scipy.org/doc/numpy-1.13.0/reference/arrays.indexing.html, Я обнаружил, что выше используется Advanced Slicing , которая возвращает копию, а не представление. Но эта копия перетасовывается на месте, поэтому результат, назначаемый исходному массиву, отсутствует.

Итак, вопрос в том, как я могу переставить элементы выбранных индексов?

Ответы [ 2 ]

0 голосов
/ 26 апреля 2018

Преступник в том, что np.random.shuffle изменяет массив на месте и никогда не возвращает значение, упорядочивая записи в произвольном порядке. Ваш код изменяет новый и временный массив, содержащий углы, который изменяется, но у вас нет на него ссылки, поэтому вы не видите никаких изменений. Проверить:

>>> import numpy as np 
>>> a = np.arange(16).reshape((4,4))
>>> a
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11],
       [12, 13, 14, 15]])
>>> np.random.shuffle(a)
>>> a
array([[12, 13, 14, 15],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11],
       [ 0,  1,  2,  3]])
>>> np.random.shuffle(a)
>>> a
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [12, 13, 14, 15],
       [ 8,  9, 10, 11]])
>>> a[[0,0,-1,-1],[0,-1,0,-1]]
array([ 0,  3,  8, 11])
>>> np.random.shuffle(a[[0,0,-1,-1],[0,-1,0,-1]])
>>> b = a[[0,0,-1,-1],[0,-1,0,-1]]
>>> np.random.shuffle(b)
>>> b
array([ 0, 11,  8,  3])
>>>  

Теперь вам просто нужно переназначить углы, используя b. И позаботьтесь, чтобы углы в моем примере были взяты из уже перетасованного массива a.

0 голосов
/ 26 апреля 2018

Вы можете использовать np.random.permutation, чтобы получить перемешанную копию входной последовательности, а затем назначить ее с помощью индексации:

In [19]: a = np.arange(16).reshape((4,4))

In [20]: a
Out[20]:
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11],
       [12, 13, 14, 15]])

In [21]: a[[0,0,-1,-1],[0,-1,0,-1]] = np.random.permutation(a[[0,0,-1,-1],[0,-1,0,-1]])

In [22]: a
Out[22]:
array([[12,  1,  2, 15],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11],
       [ 0, 13, 14,  3]])

Кроме того, вы можете получить представление из 4 углов вашего массива, используя a[::a.shape[0]-1, ::a.shape[1]-1]

Однако, поскольку результатом этого является двумерный массив numpy, перетасовка будет перетасовываться только вдоль первой оси.

...