Назначение Python в массиве против скаляра
У меня есть 2D массив A
формы (4,3)
и одномерный массив a
формы (4,)
, Я хочу поменять местами первые два ряда A
, а также первые два элемента в a
, Я сделал следующее:
A[0,:],A[1,:] = A[1,:],A[0,:]
a[0],a[1] = a[1],a[0]
Видимо, это работает для a
, но не для A
, Теперь второй ряд становится первым, но первый ряд остается неизменным. Если я сделаю следующее:
first_row_copy = A[0,:].copy()
A[0,:] = A[1,:]
A[1,:] = first_row_copy
Тогда, похоже, работает. Почему первый метод не работает? (но работает на a
) Кроме того, в чем разница между A_copy = A[0,:].copy()
а также A_copy = A[0,:]
?
1 ответ
numpy
Срезы - это представления базовой памяти, по умолчанию они не создают независимых копий (это оптимизация производительности / памяти). Так:
A[0,:],A[1,:] = A[1,:],A[0,:]
Делает вид на A[1,:]
и вид A[0,:]
затем присваивает значения A[0,:]
чтобы равняться тому, что по мнению A[1,:]
, Но когда дело доходит до назначения A[1,:]
, A[0,:]
Теперь в представлении отображаются данные после копирования, поэтому вы получите неверный результат. Просто добавив .copy
для второго элемента здесь было бы достаточно в этом случае:
A[0,:], A[1,:] = A[1,:], A[0,:].copy()
потому что кортеж справа всегда создается полностью до начала назначений слева, поэтому вы можете использовать интерактивный просмотр для первого назначения, и вам нужно только сделать копию, чтобы сохранить значения для второго назначения.