11thHeaven
11thHeaven

Reputation: 379

Python, two variables should be different but they're staying the same - is np.roll to blame?

I have an array (called image) whose rows I want to loop over and adjust using the numpy.roll function. I also want to store a copy of the row I'm about to adjust. Here's my code:

for i in range(1, 10):
    delta = function(i)     ### it's not important what this function is, just that it yields an int

    x0 =  image[i]          ### creating a variable to store the row before I change it

    print x0[:20]          ###only printing the first 20 elements, as it's a very large array

    image[i] = np.roll(x0, -delta)

    print image[i][:20]        ###image[i] has now been updated using np.roll function

    if np.array_equal(image[i], x0) == True:
        print 'something wrong'

Now is when the weird thing happens: when I run this code, I can see that x0 and image[i] are very different (as the first 20 elements of each are printed to the screen). However, I also get 'something wrong' printed to the screen, which is very confusing, as this imples that x0 and image[i] ARE equal. This is a problem, as the rest of my script relies on x0 and image[i] not being equal (except when delta = 0), but the script always treats them as though they are.

Help appreciated!

Upvotes: 0

Views: 66

Answers (3)

hpaulj
hpaulj

Reputation: 231665

This illustrates what is going on in a small array:

In [9]: x = np.arange(12).reshape(3,4)
In [10]: x
Out[10]: 
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11]])
In [11]: x0=x[0]
In [12]: x[0] = np.roll(x0, 1)
In [13]: x
Out[13]: 
array([[ 3,  0,  1,  2],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11]])
In [14]: x0
Out[14]: array([3, 0, 1, 2])

Here x0 is just another name for x[0]. Changes to x[0] are also seen in x0. x0 was changed by In [12], which could be verified with 2 prints.

DO the same, but make x0 a copy

In [15]: x0=x[1].copy()
In [16]: x[1] = np.roll(x0, 1)
In [17]: x
Out[17]: 
array([[ 3,  0,  1,  2],
       [ 7,  4,  5,  6],
       [ 8,  9, 10, 11]])
In [18]: x0
Out[18]: array([4, 5, 6, 7])

The no-copy case is the same as:

In [19]: x[2] = np.roll(x[2], 1)
In [20]: x
Out[20]: 
array([[ 3,  0,  1,  2],
       [ 7,  4,  5,  6],
       [11,  8,  9, 10]])

Upvotes: 0

Tilak Putta
Tilak Putta

Reputation: 778

You should just change as below and your problem will be solved

for i in range(1, 10):
    delta = function(i)     

    x0 =  list(image[i])    

    print x0[:20]      

    image[i] = np.roll(x0, -delta)

    print image[i][:20] 

if np.array_equal(image[i], x0) == True:
    print 'something wrong'

lets suppose x0 -> a and image[i] -> b x0 = image[i]

enter image description here

Upvotes: -1

user2357112
user2357112

Reputation: 281948

I also want to store a copy of the row I'm about to adjust

If you wanted a copy, x0 = image[i] isn't what you want. That makes a view of the row, not a copy. If you want a copy, call copy:

x0 = image[i].copy()

Upvotes: 3

Related Questions