2016-09-21 2 views
1

У меня есть следующий Numpy массив matrix,Использование Numpy массив для присвоения значений другому массиву

matrix = np.zeros((3,5), dtype = int) 

array([[0, 0, 0, 0, 0], 
     [0, 0, 0, 0, 0], 
     [0, 0, 0, 0, 0]]) 

Предположим, что у меня есть этот Numpy массив indices а

indices = np.array([[1,3], [2,4], [0,4]]) 

array([[1, 3], 
     [2, 4], 
     [0, 4]]) 

Вопрос: Как может Я назначаю 1 s элементам в matrix, где их индексы указаны в массиве indices. Ожидается векторная реализация.

Для большей ясности, результат должен выглядеть следующим образом:

array([[0, 1, 0, 1, 0], #[1,3] elements are changed 
      [0, 0, 1, 0, 1], #[2,4] elements are changed 
      [1, 0, 0, 0, 1]]) #[0,4] elements are changed 

ответ

5

Вот один подход с использованием NumPy's fancy-indexing -

matrix[np.arange(matrix.shape[0])[:,None],indices] = 1 

Объяснение

Мы создаем индексы строк с np.arange(matrix.shape[0]) -

In [16]: idx = np.arange(matrix.shape[0]) 

In [17]: idx 
Out[17]: array([0, 1, 2]) 

In [18]: idx.shape 
Out[18]: (3,) 

Индексы столбцов уже даны в indices -

In [19]: indices 
Out[19]: 
array([[1, 3], 
     [2, 4], 
     [0, 4]]) 

In [20]: indices.shape 
Out[20]: (3, 2) 

Давайте сделаем схематическую диаграмму формы индексов строки и столбца, idx и indices -

idx  (row) :  3 
indices (col) : 3 x 2 

Для использования строки и индексы столбцов для индексации во входной массив matrix, нам необходимо сделать их трансляцией друг против друга. Одним из способов было бы ввести новую ось в idx, что делает его 2D, нажав элементы в первой оси и позволяет синглтона тусклый как последняя ось с idx[:,None], как показано на рисунке ниже -

idx  (row) : 3 x 1 
indices (col) : 3 x 2 

Внутри idx бы будет транслироваться, например, так -

In [22]: idx[:,None] 
Out[22]: 
array([[0], 
     [1], 
     [2]]) 

In [23]: indices 
Out[23]: 
array([[1, 3], 
     [2, 4], 
     [0, 4]]) 

In [24]: np.repeat(idx[:,None],2,axis=1) # indices has length of 2 along cols 
Out[24]: 
array([[0, 0], # Internally broadcasting would be like this 
     [1, 1], 
     [2, 2]]) 

таким образом, транслируемые элементы из idx будут использоваться в качестве индексов строк и столбцов из индексов indices для индексации в matrix для установки элементов в нем. Так как у нас было -

idx = np.arange(matrix.shape[0]),

Таким образом, мы в конечном итоге -

matrix[np.arange(matrix.shape[0])[:,None],indices] для установки элементов.

+0

Спасибо! Сохраненный день! – akilat90

+0

Я получил свою работу с вашим подходом, но реализация несколько размыта для меня. Не могли бы вы подробнее рассказать о выполненных операциях? – akilat90

+0

@ akilat90 Посмотрите, есть ли добавленные комментарии. – Divakar

0

это включает в себя петлю и, следовательно, не может быть очень эффективным для больших массивов

for i in range(len(indices)): 
    matrix[i,indices[i]] = 1 

> matrix 
Out[73]: 
array([[0, 1, 0, 1, 0], 
     [0, 0, 1, 0, 1], 
     [1, 0, 0, 0, 1]]) 
Смежные вопросы