I probably misunderstood the term immutable/mutable and in-place change.
Creating ndarray: x = np.arange(6)
. Reshaping ndarray: x.reshape(3,2)
.
Now when I look on x
he is unchanged, the ndarray is still 1-dim.
When I do the same with a built-in python list, the list gets changed.
CodePudding user response:
The issue is that you are not overwriting the array. You are currently writing:
x = np.arange(6)
x.reshape(3,2)
But you should rather be writing:
x = np.arange(6)
x = x.reshape(3,2)
Note that the array has to be of size six to rearrange to (3,2).
CodePudding user response:
Like @morhc mentiond, you're not changing your array x
because x.reshape
returns a new array instead of modifying the existing one. Some numpy methods allow an inplace
parameter, but reshape
is not one of them.
Mutability is a somewhat related, but more general concept.
A mutable object is one that can be changed after it has been created and stored in memory. Immutable objects, once created, cannot be changed; if you want to modify an immutable object, you have to create a new one. For example, lists in python are mutable: You can add or remove elements, and the list remains stored at the same place in memory. A string however is immutable: If you take the string "foobar" and call its replace
method to replace some characters, then the modified string that you get as a result is a new object stored in a different place in memory.
You can use the id
built-in function in python to check at what memory address an object is stored. So, to demonstrate:
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
In fact, numpy arrays are in principle mutable:
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
I suppose that reshaping an object in-place would be too difficult, so instead a new one is created.
Note also that making an assignment like test_arr2 = test_arr
does not make a copy; instead, test_arr2
points to the same object in memory. If you truly want to make a new copy, you should use test_arr.copy()
.