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 Answers 4

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]])
Sign up to request clarification or add additional context in comments.

Comments

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]])

3 Comments

@PadraicCunningham yes it doesn't work :/ Edited so it now makes sense.
Yes I know it does not ;)
@PadraicCunningham now it does
0

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

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

Comments

0

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

Try with:

b = numpy.array(a)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.