Reputation: 21
I am getting some strange results from the following but am relatively new to python so may be messing something up. The following:
import numpy as np
a = np.array([1,2,3,4])
print(a)
old_a = a
for x in range(0,1):
new_a = old_a
new_a[0] = old_a[1]
new_a[1] = old_a[2]
new_a[2] = old_a[3]
new_a[3] = old_a[0]
print(new_a)
[1 2 3 4]
[2 3 4 2]
I would have expected the second array to be [2 3 4 1].
However, if I create a new array as with the "clean" def below, it seems to work
def clean(b_in):
out = np.zeros(4)
for x in range(0,4):
out[x] = b_in[x]
return out
b = np.array([1,2,3,4])
print(b)
new_b = b
for x in range(0,1):
old_b = clean(new_b)
new_b[0] = old_b[1]
new_b[1] = old_b[2]
new_b[2] = old_b[3]
new_b[3] = old_b[0]
print(new_b)
[1 2 3 4]
[2 3 4 1]
What am I missing and how do I avoid the clean def?
Thanks
**** Updated question below ****
Thanks for the responses. So, notwithstanding the response regarding the roll function below, is this the best way to do achieve the same as the roll function?
import numpy as np
a = np.array([1,2,3,4])
print(a)
old_a = a
for x in range(0,10):
new_a = old_a.copy()
new_a[0] = old_a[1]
new_a[1] = old_a[2]
new_a[2] = old_a[3]
new_a[3] = old_a[0]
old_a = new_a.copy()
print(new_a)
Thanks again
EDIT
This is what I settled on:
import numpy as np
a = np.array([1,2,3,4])
print(a)
old_a = a
new_a = np.zeros_like(old_a)
for x in range(0,10):
new_a[0] = old_a[1]
new_a[1] = old_a[2]
new_a[2] = old_a[3]
new_a[3] = old_a[0]
old_a = new_a.copy()
print(new_a)
[1 2 3 4]
[2 3 4 1]
[3 4 1 2]
[4 1 2 3]
[1 2 3 4]
[2 3 4 1]
[3 4 1 2]
[4 1 2 3]
[1 2 3 4]
[2 3 4 1]
[3 4 1 2]
Thank you all!
Upvotes: 1
Views: 15251
Reputation: 25639
See if this helps you understand what you are doing:
import numpy as np
a = np.array([1,2,3,4])
print(a)
old_a = a
for x in range(0,1):
new_a = old_a
new_a[0] = old_a[1]
print new_a
new_a[1] = old_a[2]
print new_a
new_a[2] = old_a[3]
print new_a
new_a[3] = old_a[0]
print(new_a)
[1 2 3 4]
[2 2 3 4]
[2 3 3 4]
[2 3 4 4]
[2 3 4 2]
So when you do this new_a[3] = old_a[0]
, position O
is already "2".
Below gives you what you expected.
for x in range(0,1):
new_a = old_a.copy()
new_a[0] = old_a[1]
print new_a
new_a[1] = old_a[2]
print new_a
new_a[2] = old_a[3]
print new_a
new_a[3] = old_a[0]
print(new_a)
[1 2 3 4]
[2 2 3 4]
[2 3 3 4]
[2 3 4 4]
[2 3 4 1]
The fastest way to do this is 'fancy' indexing :
a = np.array([1,2,3,4])
new_a = a[np.array([1,2,3,0])]
print new_a
array([2, 3, 4, 1])
Upvotes: 0
Reputation: 5543
When you're changing the values of new_a
you're also changing the values of old_a
as you're doing shallow copy and not deepcopy by assigning new_a = old_a
:
new_a[0] = old_a[1]
new_a[1] = old_a[2]
new_a[2] = old_a[3]
#old_a[0] is already old_a[1], as you reassigned it on line #1
new_a[3] = old_a[0]
Here's the difference between shallow and deepcopy as in Python Docs:
A shallow copy constructs a new compound object and then (to the extent possible) inserts references into it to the objects found in the original. A deep copy constructs a new compound object and then, recursively, inserts copies into it of the objects found in the original.
You can avoid your clean def by using deepcopy
or copy()
in case of numpy array:
import numpy as np
#from copy import deepcopy #for python lists
a = np.array([1,2,3,4])
print(a)
old_a = a
for x in range(0,1):
#new_a = deepcopy(old_a) #for python lists
new_a = old_a.copy() # for numpy array
new_a[0] = old_a[1]
new_a[1] = old_a[2]
new_a[2] = old_a[3]
new_a[3] = old_a[0]
print(new_a)
EDIT
After your updated question, looks like you want to update the old_a
itself, so no need to copy
it to new array, you can simply achieve what you're trying to do like this:
import numpy as np
a = np.array([1,2,3,4])
print(a)
old_a = a
for x in range(0,1):
old_a[0], old_a[1], old_a[2], old_a[3] = old_a[1], old_a[2], old_a[3], old_a[0]
print(old_a)
Upvotes: 0
Reputation: 6194
Even though this answer is not answering your question, for your specific case there is a much simpler solution, if shifting the elements by one is what you are searching for. It avoids the complexity in which you are getting stuck, and it simplifies things.
import numpy as np
a = np.array([1,2,3,4])
b = np.roll(a, -1)
print(a, b)
Output
[1 2 3 4] [2 3 4 1]
Upvotes: 2