Как установить индивидуальные индексы в массивах Numpy - PullRequest
0 голосов
/ 30 июня 2018

Я пытаюсь использовать массивы для установки значений в других массивах. К сожалению, вместо установки значения он как-то перезаписывает кучу значений. Что происходит и как я могу достичь того, чего хочу?

>>> target = np.array( [ [0,1],[1,2],[2,3] ])
>>> target
array([[0, 1],
       [1, 2],
       [2, 3]])
>>> actions = np.array([0,0,0])
>>> target[actions] #The first row, 3 times
array([[0, 1],
       [0, 1],
       [0, 1]])
>>> target[:,actions] #The first column, 3 times
array([[0, 0, 0],
       [1, 1, 1],
       [2, 2, 2]])
>>> values = np.array([7,8,9])
>>> target[:,actions] = values #why isnt this working?
>>> target
array([[9, 1],
       [9, 2],
       [9, 3]])
#Actually want
#array([[7, 1],
#       [8, 2],
#       [9, 3]])

>>> target = np.array( [ [0,1],[1,2],[2,3] ]) #reset to original value
>>> actions = np.array([0,1,0])
>>> target[:,actions] = values.reshape(3, 1)
array([[7, 7],
       [8, 8],
       [9, 9]])
#Actually want
#array([[7, 1],
#       [1, 8],
#       [9, 3]])

Ответы [ 3 ]

0 голосов
/ 30 июня 2018

Я не смог заставить его работать с использованием индексации :, однако следующее работает с использованием массива индексов. Не уверен, почему метод : не работает, если кто-то может найти способ исправить это, я приму его вместо этого.

>>> target = np.array( [ [0,1],[1,2],[2,3] ])
>>> rows = np.arange(target.shape[0])
>>> actions = np.array([0,1,0])
>>> values = np.array([7,8,9])
>>> target[rows,actions] = values
>>> target
array([[7, 1],
       [1, 8],
       [9, 3]])
0 голосов
/ 30 июня 2018

2 способа записи [7,8,9] в первый столбец:

базовая индексация (со срезом):

In [396]: target[:,0] = [7,8,9]           # all rows, 1st column
In [397]: target
Out[397]: 
array([[7, 1],
       [8, 2],
       [9, 3]])

Расширенная индексация (с 2 списками)

In [398]: target[[0,1,2],[0,0,0]] = [7,8,9]   # pair [0,0],[1,0],[2,0]
In [399]: target
Out[399]: 
array([[7, 1],
       [8, 2],
       [9, 3]])

2-й метод также работает для смеси столбцов:

In [400]: target = np.array( [ [0,1],[1,2],[2,3] ])
In [401]: target[[0,1,2],[0,1,0]] = [7,8,9]
In [402]: target
Out[402]: 
array([[7, 1],
       [1, 8],
       [9, 3]])

Вещание вступает в игру. В таком случае есть 3 потенциальных массива для широковещания - 2 измерения и исходный массив.

При таком расширенном индексировании получается 1d массив. Таким образом, исходный массив должен соответствовать:

In [403]: target[[0,1,2],[0,1,0]]
Out[403]: array([7, 8, 9])

A (1,3) может передавать на (3,), но (3,1) не может:

In [404]: target[[0,1,2],[0,1,0]] = np.array([[7,8,9]])
In [405]: target[[0,1,2],[0,1,0]] = np.array([[7,8,9]]).T
...
ValueError: shape mismatch: value array of shape (3,1) could not be broadcast to indexing result of shape (3,)

Этот вид индексации необычен. Обратите внимание, что результат (3,3).

In [412]: target[:,[0,0,0]]
Out[412]: 
array([[0, 0, 0],
       [1, 1, 1],
       [2, 2, 2]])

A (3,1) источник:

In [413]: np.array([[7,8,9]]).T
Out[413]: 
array([[7],
       [8],
       [9]])
In [414]: target[:,[0,0,0]] = _
In [415]: target
Out[415]: 
array([[7, 1],
       [8, 2],
       [9, 3]])

(3,1) может транслировать на (3,3). Это работает, но в итоге назначается [7,8,9] 3 раза, все в один и тот же столбец 0.


Другой способ назначения 1-го столбца:

In [423]: target[np.ix_([0,1,2],[0,0,0])]
Out[423]: 
array([[0, 0, 0],
       [1, 1, 1],
       [2, 2, 2]])

Снова a (3,3), с принимает (3,1):

In [424]: target[np.ix_([0,1,2],[0,0,0])] = np.array([[7,8,9]]).T
In [425]: target
Out[425]: 
array([[7, 1],
       [8, 2],
       [9, 3]])

ix_ создает 2 массива, которые могут транслироваться друг против друга, в данном случае вектор столбца и строка один:

In [426]: np.ix_([0,1,2],[0,0,0])
Out[426]: 
(array([[0],
        [1],
        [2]]), array([[0, 0, 0]]))

Я могу выбрать все элементы target с помощью:

In [430]: target[np.ix_([0,1,2],[0,1])]
Out[430]: 
array([[0, 1],
       [1, 2],
       [2, 3]])

и в беспорядочном порядке:

In [431]: target[np.ix_([2,0,1],[1,0])]
Out[431]: 
array([[3, 2],
       [1, 0],
       [2, 1]])
0 голосов
/ 30 июня 2018

target[:,actions] выбирает тот же столбец из target трижды.

Когда вы говорите target[:,actions] = values, вы делаете:

  1. Назначьте 7 всем значениям в столбце три раза.
  2. Назначьте 8 всем значениям в столбце три раза.
  3. Назначьте 9 всем значениям в столбце три раза.

Таким образом, вы получите 9 во всех значениях в столбце.

Если вы настаиваете на этой неуклюжей тройной записи данных, вы можете исправить это путем транспонирования записи:

target[:,actions] = values.reshape(3, 1)

Это напишет [7,8,9] в столбец три раза. Очевидно, это расточительно, и вы могли бы сделать это вместо этого:

target[:,actions[-1]] = values

Эффект должен быть таким же, и он сохраняет вычисления.

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