Это на самом деле не проблема вообще; это способ, которым массивы (и другие объекты) работают на Python.
Подумайте об этом так: массив, который вы создали в вашем примере кода, является объектом, который находится в каком-либо месте в памяти. Но вы не можете использовать его в своей программе, говоря Python, где в памяти идти искать его; вы должны дать ему имя. Когда вы пишете
a = np.array([[1,2],[3,4]])
вы оба создания массива и создать имя, a
, что относится к нему. С этого момента Python знает, что a
ссылается на «адрес памяти 0x123674283» (или что-то еще). Там есть внутренняя таблица в среде выполнения Python (так называемая «таблицей символов», если я правильно помню), которая содержит всю эту информацию, так что после того, как выше строка кода Python работает, эта таблица будет содержать
...,
'a' : 0x123674283,
...
При назначении значение одной переменной в другую, как
b = a
Python не копирует весь массив, потому что если бы это был большой массив, это заняло бы много времени. Вместо этого он переходит в таблицу символов и копирует адрес памяти для a
в новую строку в таблице для b
. Таким образом, вы завершаете с
...,
'a' : 0x123674283,
...,
'b' : 0x123674283,
...
Итак, вы видите, a
и b
фактически ссылаясь на то же место в памяти, то есть тот же объект. Любые изменения, внесенные вами в один, будут отражены в другом, так как они всего лишь два имени для одного и того же.
Если вы хотите сделать копию массива, вы должны вызвать метод, чтобы сделать это явно. У массивов Numpy есть метод copy
, который вы можете использовать только для этой цели. Так что, если вы пишете
b = a.copy()
тогда Python будет первым фактически сделать копию массива - то есть, он выделяет новую область памяти, скажем, по адресу 0x123904381, затем идет в адрес памяти 0x123674283 и копии всех значения массива от последнего раздела памяти до первого. Таким образом, у вас есть одно и то же содержание, сидящее в двух разных местах в памяти.
...,
'a' : 0x123674283,
...,
'b' : 0x123904381,
...
Теперь, когда вы измените один из элементов b
, что изменения не будут отображаться в a
, так как a
и b
больше не относятся к одной и той же секции памяти компьютера. Поскольку есть две независимые копии данных массива, вы можете изменить один, не затрагивая другой.
Благодарю вас за отличное описание. Излишне говорить, что это устранило проблему, но я действительно ценю, что вы тратите время на объяснение. Ты просветил меня! – Sujan
«Python не копирует весь массив, потому что если бы это был большой массив, это заняло бы много времени». - Я бы сказал, что речь идет не о времени, которое потребуется, и о том, что если вы не реализуете такие вещи таким образом, вам нужно ввести что-то вроде отдельного типа указателя, и это усложняет ситуацию. – user2357112