0

I stumbled today upon this issue and I cannot see what's the problem:

print(np.unique(label))
>>> [0. 1. 2. 3. 4.]

LAC = label
print(np.unique(LAC))
>>> [0. 1. 2. 3. 4.]

print(np.unique(label))
>>> [0. 1. 2. 3. 4.]

LAC[LAC != 4] = 0
LAC[LAC == 4] = 1

print(np.unique(LAC))
>>> [0. 1.]

print(np.unique(label))
>>> [0. 1.]

Is it somethings I do wrong ? label is a numpy array (44,640,640) and LAC is just supposed to be the copy of label but for some reason it gets affected too ?

I don't understand where this comes from. Does anyone have an idea ?

Ehsan
  • 12,072
  • 2
  • 20
  • 33
Unic0
  • 341
  • 1
  • 3
  • 19

1 Answers1

1

LAC = label does NOT copy label into a new array. It is simply assigning the same object to LAC. Thus, when you change one, the other also changes. Think of it as both being the same array with different names.

If you wish to make a new copy of your array, use np.copy. Here is an example to make it clear:

label = np.array([0., 1., 2., 3., 4., 0., 1., 2., 3., 4.])
print(np.unique(label))
#[0. 1. 2. 3. 4.]

#LAC and label point to the same object
LAC = label
#this changes both LAC and label
LAC[LAC != 4] = 0

print(np.unique(LAC))
#[0. 4.]

print(np.unique(label))
#[0. 4.]


label = np.array([0., 1., 2., 3., 4., 0., 1., 2., 3., 4.])
#make a new copy of label
LAC = label.copy()
#this changes ONLY LAC
LAC[LAC != 4] = 0

print(np.unique(LAC))
#[0. 4.]

print(np.unique(label))
#[0. 1. 2. 3. 4.]
Ehsan
  • 12,072
  • 2
  • 20
  • 33
  • Indeed, I didn't know that. Is it the same with all variables or this concerns just numpy array ? I just tried and you are completely right ! I should be more careful. Thank you very much – Unic0 Jul 31 '20 at 02:13
  • @Ehsan **NO** it does **not** depend on the type of object, **assignment never copies**. Not `float` or `int` or *anything*. All objects have the exact same semantics as far as assignment goes in Python. – juanpa.arrivillaga Jul 31 '20 at 02:52
  • @Unic0 just to be clear, assignment *never* copies, regardless of the type. You should read the following: https://nedbatchelder.com/text/names.html – juanpa.arrivillaga Jul 31 '20 at 02:55
  • 1
    A float doesn't make a copy, but it isn't mutable. So this kind of a problem doesn't arise. – hpaulj Jul 31 '20 at 05:25
  • @juanpa.arrivillaga Thanks for pointing out the language. I tried to explain the same thing with wrong words. The correct term is rebinding and mutating. Floats are rebinded and arrays are mutable (assuming you don't define a type and twist python assignment) – Ehsan Jul 31 '20 at 05:39
  • @Ehsan I'm not sure what you are saying, but again, just to be clear, assignment always rebinds regardless of the type. Immutable types simply lack mutator methods, but the semantics of assignment is always the same. – juanpa.arrivillaga Jul 31 '20 at 05:40
  • @juanpa.arrivillaga just as counter-example for overloading assignment for methods: https://gist.github.com/jamalex/5997735 Nonetheless, the simple assignments do not copy as you said. – Ehsan Jul 31 '20 at 06:56
  • @Ehsan That is specifically *attribute assignment*, where yes, the behavior can be controlled by the type. But you can never change the way `name = whatever` works. – juanpa.arrivillaga Jul 31 '20 at 06:57