Numpy: поменять местами 2D массив на основе отдельного вектора - PullRequest
0 голосов
/ 17 сентября 2018

Допустим, у меня есть массив 3x3:

[[0, 1, 2],
 [2, 0, 1],
 [1, 2, 0]]

И дополнительный вектор:

[2,
 1,
 1]

Для каждой строки в матрице я хочу поменять местами номер по 0-му индексу с номером по соответствующему индексу из вектора. В этом примере после свопа конечный результат будет:

[[2, 1, 0], # the 0th and 2nd positions have been swapped
 [0, 2, 1], # the 0th and 1st positions have been swapped
 [2, 1, 0]] # the 0th and 1st positions have been swapped

Как ты можешь это сделать?

Ответы [ 2 ]

0 голосов
/ 17 сентября 2018
import numpy as np

A = np.asarray([[0, 1, 2],
                [2, 0, 1],
                [1, 2, 0]])

col_idxs = np.asarray([2, 1, 1])
row_idxs = np.arange(len(A))
a = A[:, 0].copy()
A[:, 0] = A[row_idxs, col_idxs]
A[row_idxs, col_idxs] = a

или более кратко

c = np.asarray([2, 1, 1])
r = np.arange(len(A))
A[:, 0], A[r, c] = A[r, c], A[:, 0].copy()

Здесь мы используем тот факт, что мы можем индексировать отдельные элементы массива numpy, предоставляя ему два отдельных объекта типа списка для соответствующих индексов строк и столбцов.

Таким образом, строка A[:, 0], A[r, c] = A[r, c], A[:, 0].copy() может быть прочитана, поскольку получить индексированные элементы из каждого столбца и поменять их местами с первым столбцом.

Редактировать

Спасибо @Paul Panzer за его комментарий, назначение можно сделать еще короче, записав его как A[r, c], A[:, 0] = A[:, 0], A[r, c].

Обратите внимание, что порядок присвоения A[r, c] и A[:, 0] изменился по сравнению с более ранней версией.

Причина, по которой копию здесь можно опустить, заключается в том, что

  1. В задании правая часть полностью оценивается перед присвоение переменных слева.
  2. Необычное индексирование Numpy (A[r, c] здесь) возвращает копию в отличие кусочки (A[:, 0]), которые возвращают представление.

Следовательно, то, что говорит эта новая строка кода:

  1. Получить представление (т. Е. Ссылку) на первый столбец A
  2. Создать копию A[r, c]. Копия неявная из-за необычной индексации массива Numpy.
  3. Назначьте A[r, c] значения первого столбца A, используя вид этого столбца.
  4. Присвойте первому столбцу A копию A[r, c], которую мы сделали ранее (обратите внимание, что к этому моменту A[r, c] уже был назначен старый значение A[:, 0].)

Кроме того, нам не нужно преобразовывать индексы в массив Numpy.

c = [2, 1, 1]
r = range(len(A))
A[r, c], A[:, 0] = A[:, 0], A[r, c]
0 голосов
/ 17 сентября 2018
a= np.array([[0,1,2],[2,0,1],[1,2,0]])
b=[2,1,1]
for rc, r in enumerate(a):
    r[0], r[b[rc]] =  r[b[rc]], r[0]
print(a)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...