Допустим, у меня есть массив 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

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

1
JavaNewb 17 Сен 2018 в 04:03

2 ответа

Лучший ответ
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, предоставляя ему два отдельных объекта в виде списка для соответствующих индексов row и col.

Таким образом, строку 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]
1
lightalchemist 17 Сен 2018 в 05:02
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)
0
user12075 17 Сен 2018 в 01:11