为什么 ndarray 函数作为不可变对象

Why ndarray function as immutable object

我可能误解了术语 immutable/mutable 和就地更改。

正在创建 ndarray:x = np.arange(6)。重塑 ndarray:x.reshape(3,2).

现在我看x他没变,ndarray还是1-dim。

当我对内置 python 列表执行相同操作时,列表发生了变化。

问题是您没有覆盖数组。您目前正在写:

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

但你应该这样写:

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

请注意,数组的大小必须为 6 才能重新排列为 (3,2)。

就像@morhc 提到的那样,您没有更改数组 x 因为 x.reshape returns 一个新数组而不是修改现有数组。一些 numpy 方法允许 inplace 参数,但 reshape 不是其中之一。

可变性是一个有点相关但更笼统的概念。

可变对象是指在创建并存储在内存中后可以更改的对象。不可变对象一旦创建,就无法更改;如果你想修改一个不可变的对象,你必须创建一个新的。例如,python 中的列表是可变的:您可以添加或删除元素,并且列表仍然存储在内存中的同一位置。然而,字符串是不可变的:如果您使用字符串“foobar”并调用它的 replace 方法来替换一些字符,那么您得到的修改后的字符串就是一个存储在内存中不同位置的新对象。

您可以使用python中的id内置函数来检查对象存储在哪个内存地址。所以,为了证明:

test_list = []
id(test_list)
>>> 1696610990848 # memory address of the empty list object we just created
test_list.append(1)
id(test_list)
>>> 1696610990848 # the list with one item added to it is still the same object

test_str = "foobar"
id(test_str)
>>> 1696611256816 # memory address of the string object we just created
test_str = test_str.replace("b", "x")
id(test_str)
>>> 1696611251312 # the replace method returned a new object

事实上,numpy 数组 原则上是 可变的:

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

我想就地重塑对象太难了,所以创建了一个新对象。

另请注意,像 test_arr2 = test_arr 这样的赋值 不会 复制;相反,test_arr2 指向内存中的同一个对象。如果你真的想制作一个新的副本,你应该使用 test_arr.copy().