在循环中更新numpy数组

时间:2017-10-14 20:14:02

标签: python arrays numpy

我从以下方面得到了一些奇怪的结果,但对python来说相对较新,所以可能会弄乱一些东西。以下内容:

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]

我原本期望第二个数组是[2 3 4 1]。

但是,如果我使用下面的“clean”def创建一个新数组,它似乎可以正常工作

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]

我缺少什么,如何避免干净?

由于

****以下更新了问题****

感谢您的回复。因此,尽管下面有关于滚动功能的响应,这是实现与滚动功能相同的最佳方法吗?

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)

再次感谢

修改

这就是我所确定的:

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]

谢谢大家!

3 个答案:

答案 0 :(得分:0)

当您更改new_a的值时,您还要更改old_a的值,因为您正在执行浅拷贝而不是深度复制,只需指定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] 

这是浅层和深层复制之间的区别,如Python Docs

  

浅复制构造一个新的复合对象,然后(尽可能)将对它的引用插入到原始对象中找到的对象。   深拷贝构造一个新的复合对象,然后递归地将副本插入到原始对象中找到的对象。

如果是numpy数组,您可以使用deepcopycopy()来避免干净def:

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)

修改

在您更新了问题后,看起来您想要更新old_a本身,因此无需copy更新到新数组,您只需实现您想要执行的操作:

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)

答案 1 :(得分:0)

看看这是否有助于您了解自己在做什么:

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]

因此,当您new_a[3] = old_a[0]执行此操作时,位置O已经是" 2"。 下面给出了你的期望。

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]

实现这一目标的最快方法是“花哨的”'索引:

a     = np.array([1,2,3,4])
new_a = a[np.array([1,2,3,0])]
print new_a

array([2, 3, 4, 1])

答案 2 :(得分:0)

即使这个答案没有回答你的问题,但对于你的具体情况,有一个更简单的解决方案,如果将元素换成一个就是你要搜索的内容。它避免了您遇到困难的复杂性,并简化了事情。

import numpy as np

a = np.array([1,2,3,4])
b = np.roll(a, -1)
print(a, b)

输出

[1 2 3 4] [2 3 4 1]