Почему функция ndarray функционирует как неизменяемый объект

#python #immutability #numpy-ndarray

Вопрос:

Я, вероятно, неправильно понял термин неизменяемый/изменяемый и изменение на месте.

Создание ndarray: x = np.arange(6) . Изменение формы ndarray: x.reshape(3,2) .

Теперь, когда я смотрю на x него, он не изменился, ndarray по-прежнему 1-тусклый.

Когда я делаю то же самое со встроенным списком python, список изменяется.

Ответ №1:

Как упоминал @morhc, вы не меняете свой массив x , потому x.reshape что возвращаете новый массив вместо изменения существующего. Некоторые методы numpy допускают inplace параметр, но reshape не являются одним из них.

Изменчивость-это несколько родственное, но более общее понятие.

Изменяемый объект-это объект, который можно изменить после того, как он был создан и сохранен в памяти. Неизменяемые объекты, однажды созданные, не могут быть изменены; если вы хотите изменить неизменяемый объект, вы должны создать новый. Например, списки в python изменчивы: вы можете добавлять или удалять элементы, и список остается сохраненным в том же месте в памяти. Строка, однако, неизменна: если вы возьмете строку «foobar» и вызовете ее replace метод для замены некоторых символов, то измененная строка, которую вы получите в результате, будет новым объектом, хранящимся в другом месте в памяти.

Вы можете использовать id встроенную функцию в python, чтобы проверить, по какому адресу памяти хранится объект. Итак, чтобы продемонстрировать:

 test_list = [] id(test_list) gt;gt;gt; 1696610990848 # memory address of the empty list object we just created test_list.append(1) id(test_list) gt;gt;gt; 1696610990848 # the list with one item added to it is still the same object  test_str = "foobar" id(test_str) gt;gt;gt; 1696611256816 # memory address of the string object we just created test_str = test_str.replace("b", "x") id(test_str) gt;gt;gt; 1696611251312 # the replace method returned a new object  

На самом деле массивы numpy в принципе изменчивы:

 test_arr = np.zeros(4) id(test_arr) gt;gt;gt; 1696611361200 test_arr[0] = 1 id(test_arr) gt;gt;gt; 1696611361200 # after changing an entry in the array, it's still the same object  

Я полагаю, что изменить объект на месте было бы слишком сложно, поэтому вместо этого создается новый.

Обратите также внимание, что выполнение подобного назначения test_arr2 = test_arr не создает копию; вместо test_arr2 этого указывает на один и тот же объект в памяти. Если вы действительно хотите сделать новую копию, вам следует ее использовать test_arr.copy() .

Ответ №2:

Проблема в том, что вы не перезаписываете массив. В настоящее время вы пишете:

 x = np.arange(6) x.reshape(3,2)  

Но тебе лучше бы писать:

 x = np.arange(6) x = x.reshape(3,2)  

Обратите внимание, что массив должен быть шестого размера, чтобы изменить его на (3,2).