адрес памяти numpy элементов - PullRequest
2 голосов
/ 14 февраля 2020

См. Фрагмент кода ниже

a = [[1, 2], [3, 4], [5, 6]]
b = a[1]
id(a[1]) == id(b) # True

Это легко понять, поскольку адрес b и адрес a[1] совпадают. Поэтому, если я изменю элемент в a += 1, элемент в b также изменится b == [4, 5].

Однако, если я изменил на массив numpy, дело обстоит иначе

c = numpy.array(a)
d = c[1]
id(c[1]) == id(d) # False

Однако, если я изменю элемент в c c +=1, элементы в d также изменятся (d изменится на array([4, 5])), я не понимаю двух вещей: 1. почему адрес d а адрес c[1] отличается? 2. если адрес другой, почему элементы изменились одновременно? Кто-нибудь мог объяснить? Спасибо

1 Ответ

1 голос
/ 14 февраля 2020

Каждый раз, когда к внутреннему ndarray ndarray обращаются через индексацию, как вы это делали с c[1], новый ndarray создается на лету как представление памяти (буфера). В этой строке id(c[1]) == id(d), c[1] и d представляют собой два отдельных экземпляра ndarray, чьи поля data указывают на один и тот же адрес памяти (называемый «областью данных» в numpy do c). Рассмотрим следующее:

a = [[1, 2], [3, 4], [5, 6]]
c = np.array(a)
d = c[0]
e = c[0]
f = c[1]
print(id(d) == id(e)) # False
print(d.__array_interface__['data'][0] == e.__array_interface__['data'][0]) # True
print(d.__array_interface__['data'][0] == f.__array_interface__['data'][0]) # False

Расположение данных, хранящихся у каждого ndarray, можно найти в интерфейсе массива . А поскольку d и e указывают на одни и те же данные по одному и тому же адресу памяти, адрес данных будет одинаковым. И наоборот, d и f не указывают на одни и те же данные, поэтому их указатели отличаются.

...