Python - копирование / назначение массива, неожиданное поведение '= array [:]' для numpy - PullRequest
1 голос
/ 28 апреля 2020

Я читал о копировании массивов (& списка) по ссылке или значению. Однако, я столкнулся с проблемой здесь .. Чтобы показать мою проблему, я сделал три примера, каждый с присваиванием и изменением.

Первый пример: По умолчанию он копируется reference.
Таким образом, изменение влияет на a и ArrayA, оба имеют один и тот же адрес. OK

Второй пример: Так как правая часть вычисляется первой, * 1 не меняет своего значения, но приводит к копированию по значению. (Я думаю, что это можно сделать и несколькими другими способами, например, используя copy () и ..)
Таким образом, изменение влияет только на c, имея адрес, отличный от массива C. OK

Третий пример: Здесь я добавляю [:] к массиву, копируя таким образом массив (= по значению), насколько я понимаю. Это может быть подтверждено различными адресами e и ArrayE. Однако изменение влияет не только на e, но и на ArrayE. Для меня это довольно неожиданно, поскольку раньше мне даже показывали разные адреса. ПОЧЕМУ?

Спасибо вперед =)

import numpy as np
# Example 1, by reference
ArrayA = np.array([5,2,3,5,4])
ArrayB = np.array(  [1,2,3,4])

a = ArrayA
a[1:] += ArrayB

print("{}:\t{},\tid: {}".format("ArrayA",ArrayA, id(ArrayA) ))
print("{}:\t  {},\tid: {}".format("ArrayB",ArrayB, id(ArrayB) ))
print("{}:\t{},\tid: {}".format("a",a, id(a) ))

ArrayC = np.array([5,2,3,5,4])
ArrayD = np.array(  [1,2,3,4])


# Example 2, by value
c = ArrayC*1
c[1:] += ArrayD

print()
print("{}:\t{},\tid: {}".format("ArrayC",ArrayC, id(ArrayC) ))
print("{}:\t  {},\tid: {}".format("ArrayD",ArrayD, id(ArrayD) ))
print("{}:\t{},\tid: {}".format("c",c, id(c) ))

# Example 3, by reference/value?!?!
ArrayE = np.array([5,2,3,5,4])
ArrayF = np.array(  [1,2,3,4])

e = ArrayE[:]
e[1:] += ArrayF

print()
print("{}:\t{},\tid: {}".format("ArrayE",ArrayE, id(ArrayE) ))
print("{}:\t  {},\tid: {}".format("ArrayF",ArrayF, id(ArrayF) ))
print("{}:\t{},\tid: {}".format("e",e, id(e) ))
ArrayA: [5 3 5 8 8],    id: 2450575020480
ArrayB:   [1 2 3 4],    id: 2450575021680
a:      [5 3 5 8 8],    id: 2450575020480

ArrayC: [5 2 3 5 4],    id: 2450575021280
ArrayD:   [1 2 3 4],    id: 2450575022080
c:      [5 3 5 8 8],    id: 2450575022240

ArrayE: [5 3 5 8 8],    id: 2450575022640
ArrayF:   [1 2 3 4],    id: 2450575022000
e:      [5 3 5 8 8],    id: 2450575022880

1 Ответ

0 голосов
/ 28 апреля 2020

РЕДАКТИРОВАНИЕ - см. Комментарии @ juanpa.arrivillaga ниже.

Во всех ваших примерах значения из ndarrays являются
numpy.int32 объектами, которые изменяемы .
Итак, из вашего третьего Например, и e, и ArrayE указывают на одни и те же numpy.int32 объекты.
Именно поэтому изменения отражаются на обоих.
Это можно проверить, проверив их идентификаторы.

print(id(e[0]) == id(ArrayE[0]))
...