0

I wanna manipulate the matrix "b", but since I've assigned its initial value equal to initial value of matrix "a", the matrix "a" is also gets manipulated which is not desired. How can I solve this problem?

import numpy as np
a=np.zeros((3,3))
b=a
b[0,:]=1
print('a=',a,'\n')

print('b=',b)

And the result of this code is this:

a= [[1. 1. 1.]
 [0. 0. 0.]
 [0. 0. 0.]] 

b= [[1. 1. 1.]
 [0. 0. 0.]
 [0. 0. 0.]]

As you see both of these matrices have been modified. I wrote this little code to illustrate my problem. My main program is a bigger one but I've recognized the issue and this is it.

Mohammad Amin
  • 56
  • 1
  • 7

2 Answers2

2

The line b = a should be b = a.copy().

import numpy as np

a = np.zeros((3,3))
b = a.copy()
b[0,:] = 1
print('a = ',a,'\n')
print('b = ',b)
a = [[0. 0. 0.]
 [0. 0. 0.]
 [0. 0. 0.]] 
b = [[1. 1. 1.]
 [0. 0. 0.]
 [0. 0. 0.]]
Timothy Helton
  • 332
  • 4
  • 10
2

Since arrays a & b are both mutable objects in python, a simple = makes them point to the same location in memory -- hence, a change to a results in a change to b as well. This is called a shallow copy.

What you are looking for is a deep copy:

b = a.copy()

See this tutorial for more details on shallow vs deep copies, or this one.

Built-in types like int, float, etc. are immutable objects in python, so there is no shallow copy.

Emily
  • 36
  • 4
  • 1
    *everything* is an object in python – juanpa.arrivillaga Feb 08 '21 at 18:36
  • Yes, thank you for that clarification. For immutable objects like ints or floats, the = makes a separate (deep) copy in memory, there is no shallow copy. – Emily Feb 08 '21 at 21:03
  • 1
    The terminology in the Geeks tutorial is wrong. In `numpy` a `view` should not be be called a 'shallow copy'. And `array.copy()` is not a 'deep copy'. The `copy` module has a `deepcopy`, which for `numpy` only matters if the dtype is object. – hpaulj Feb 08 '21 at 21:10
  • `a = b` is not a copy of any sort, shallow or not. It just makes `a` reference the same object as `b`. The OP was bitten by this distinction. But with `numpy` arrays, we need to also distinguish between a `view` and a `copy`. – hpaulj Feb 08 '21 at 21:13
  • https://docs.python.org/3/library/copy.html - for the distinction between `copy` and `deepcopy` as implemented in the `copy` module. – hpaulj Feb 08 '21 at 21:17
  • @Emily no, it *absolutely does not*. Assignment always works exactly the same way, regardless of type. It always simply creates a new reference to an object. It *never copies*, again, regardless of the type. You can verify this yourself: `x = 3.14156; y = x; print(id(x), id(y))`. People get this idea frequently, and I think it's because when you have an immutable type, you can never get the surprising behavior like in the OP, but that's because they are *immutable*, not because assignment creates any sort of copy. – juanpa.arrivillaga Feb 08 '21 at 22:28