2

I have a problem assigning values to variables in Python

import numpy
a = numpy.empty((3,3,))
a[:] = numpy.NaN
a
b=a
b[numpy.isnan(b)]=1

upto the second-to-last line a and b are equal to NaN arrays:

>>> a
array([[ nan,  nan,  nan],
       [ nan,  nan,  nan],
       [ nan,  nan,  nan]])
>>> b
array([[ nan,  nan,  nan],
       [ nan,  nan,  nan],
       [ nan,  nan,  nan]])

but when the last statement is executed (i.e. b[numpy.isnan(b)]=1) both a and b become arrays of ones

>>> a
array([[ 1.,  1.,  1.],
       [ 1.,  1.,  1.],
       [ 1.,  1.,  1.]])
>>> b
array([[ 1.,  1.,  1.],
       [ 1.,  1.,  1.],
       [ 1.,  1.,  1.]])

how can I set array b to ones and array a to NaN. Note that I need to maintain the b=a statement

4 Answers4

2

You can use

 b=numpy.copy(a)

Then b[numpy.isnan(b)]=1

In [45]: a[:] = numpy.NaN

In [46]: b=numpy.copy(a)

In [47]: b[numpy.isnan(b)]=1

In [48]: a
Out[48]: 
array([[ nan,  nan,  nan],
       [ nan,  nan,  nan],
       [ nan,  nan,  nan]])

In [49]: b
Out[49]: 
array([[ 1.,  1.,  1.],
       [ 1.,  1.,  1.],
       [ 1.,  1.,  1.]])

Using b =a[:] will NOT work in your example the values will change if you alter either array.

In [102]: import numpy

In [103]: a = numpy.empty((3,3,))

In [104]: a[:] = numpy.NaN

In [105]: a
Out[105]: 
array([[ nan,  nan,  nan],
       [ nan,  nan,  nan],
       [ nan,  nan,  nan]])

In [106]: b=a[:]

In [107]: b
Out[107]: 
array([[ nan,  nan,  nan],
       [ nan,  nan,  nan],
       [ nan,  nan,  nan]])

In [108]: b[numpy.isnan(b)]=1

In [109]: a
Out[109]: 
array([[ 1.,  1.,  1.],
       [ 1.,  1.,  1.],
       [ 1.,  1.,  1.]])

In [110]: b
Out[110]: 
array([[ 1.,  1.,  1.],
       [ 1.,  1.,  1.],
       [ 1.,  1.,  1.]])
In [111]: a[:] = numpy.NaN

In [112]: a
Out[112]: 
array([[ nan,  nan,  nan],
       [ nan,  nan,  nan],
       [ nan,  nan,  nan]])

In [113]: b
Out[113]: 
array([[ nan,  nan,  nan],
       [ nan,  nan,  nan],
       [ nan,  nan,  nan]])
Padraic Cunningham
  • 176,452
  • 29
  • 245
  • 321
1

The problem that you are having is that objects in python are pass by reference meaning that when you think you've copied it, it's really just a shadow of the original and any changes get reflected back.

You need to use numpy.copy() The pythonic way to clone an array is by slicing:

b = a[:]

But that doesn't work for numpy.ndarrays because they have different behaviour. Slicing does not create a copy therefore you must use:

b = numpy.copy(a)

See:

Bug or feature: cloning a numpy array w/ slicing

Proof:

>>> def setOnes(nparr):
...     nparr[:] = 1
...
>>> a = numpy.empty((3,3,))
>>> a[:] = numpy.NaN
>>> b = a[:]
>>> a
array([[ nan,  nan,  nan],
       [ nan,  nan,  nan],
       [ nan,  nan,  nan]])
>>> setOnes(a)
>>> a
array([[ 1.,  1.,  1.],
       [ 1.,  1.,  1.],
       [ 1.,  1.,  1.]])
>>> b
array([[ 1.,  1.,  1.],
       [ 1.,  1.,  1.],
       [ 1.,  1.,  1.]])
>>> a[:] = numpy.NaN
>>> a
array([[ nan,  nan,  nan],
       [ nan,  nan,  nan],
       [ nan,  nan,  nan]])
>>> b = numpy.copy(a)
>>> b
array([[ nan,  nan,  nan],
       [ nan,  nan,  nan],
       [ nan,  nan,  nan]])
>>> setOnes(b)
>>> b
array([[ 1.,  1.,  1.],
       [ 1.,  1.,  1.],
       [ 1.,  1.,  1.]])
>>> a
array([[ nan,  nan,  nan],
       [ nan,  nan,  nan],
       [ nan,  nan,  nan]])
Community
  • 1
  • 1
nettux
  • 5,270
  • 2
  • 23
  • 33
0

look into the copy module. I think deepcopy is what you want.

Alternatively, instead of b=a, you can write b=a[:].

Chris Irwin
  • 117
  • 3
  • 10
0

b = a copies a reference into b and not a referenced object contents.

Try with:

b = numpy.array(a)