Я пытался сделать неглубокую копию массивов numpy, используя [:], как обычно делал бы со списками. Однако я обнаружил, что это не ведет себя так же, как списки. Я знаю, что могу использовать метод .copy (), чтобы решить эту проблему. Но просто хотел понять, что происходит здесь под капотом с numpy. может кто-нибудь уточнить.

import numpy as np
a = np.array([1,2,3,4,5])
b = a[:]
print(id(b) == id(a))  # Ids are different, So different objects right ?
b[3] = 10
print(a, b) # Both a and b got updated
1
Ak4704 11 Окт 2021 в 13:33

2 ответа

Лучший ответ

Из документации по нарезке (выделено мной ):

Обратите внимание, что срезы массивов копируют не данные внутреннего массива, а создавать только новые просмотры исходных данных. Это отличается от нарезка списка или кортежа и явное копирование () рекомендуется, если исходные данные больше не требуются.

Так что просто сделай:

import numpy as np

a = np.array([1, 2, 3, 4, 5])
b = a.copy()
b[3] = 10
print(a, b)

Вывод

[1 2 3 4 5] [ 1  2  3 10  5]

Обратите внимание на то, что идентификаторы отличаются по той причине, что b является представлением a и действительно другим объектом.

1
Dani Mesejo 11 Окт 2021 в 10:47

Оператор [:] в numpy копирует не данные, а ссылку. Так что такое поведение ожидается. Это то же самое, что вы делаете a = b напрямую. Используйте np.copy(array), чтобы скопировать значения.

Если есть массив a = [1, 2] и пустая переменная b, то поведение присваиваний массива numpy суммируется следующим образом:

  1. Такие назначения будут копировать ссылку, поэтому, если вы измените b позже, он также изменит a.
b = a
b[1] = 10
print(b == a) # True
b = a[:]
b[1] = 10
print(b == a) # True
  1. При таком назначении будут скопированы значения , поэтому, если вы измените b позже, a не изменится.
b = np.copy(a)
b[1] = 10
print(b == a) # True

... и если dtype=object, использование deepcopy() из пакета copy обеспечит копирование всех значений.

b = copy.deepcopy(a)
b[1] = 10
print(b == a) # True
0
Dhana D. 11 Окт 2021 в 10:47