我有两个向量, posVec 和 dirVec 我想要保持的值(0.0,0.0,0.0)。
所以我设置了临时向量 t_pos & t_dir 并根据 cylCut
的值更改其值然后在循环的下一次迭代中,我重置了临时向量。
代码:
import numpy as np
posVec = np.array([0.0,0.0,0.0]) # orginal vectors
dirVec = np.array([0.0,0.0,0.0])
print "................."
print 'Before'
print "................."
print posVec
print dirVec
print "................."
for cylCut in range(0,3):
t_pos = posVec # temporary vectors
t_dir = dirVec
if cylCut == 0: # set temp vects accordingly
print '0'
t_pos[0] = 1.0
t_dir[0] = 1.0
if cylCut == 1:
print '1'
t_pos[1] = 1.0
t_dir[1] = 1.0
if cylCut == 2:
print '2'
t_pos[2] = 1.0
t_dir[2] = 1.0
print t_pos
print t_dir
print "................."
print 'After'
print "................."
print posVec
print dirVec
print "................."
由于未知原因(至少对我而言) posVec & posDir 也正在改变。
我得到的输出,
.................
Before
.................
[ 0. 0. 0.]
[ 0. 0. 0.]
.................
0
[ 1. 0. 0.]
[ 1. 0. 0.]
1
[ 1. 1. 0.]
[ 1. 1. 0.]
2
[ 1. 1. 1.]
[ 1. 1. 1.]
.................
After
.................
[ 1. 1. 1.]
[ 1. 1. 1.]
.................
为什么会这样?我没有明确地改变向量。 Python / Numpy会自动链接变量吗?为什么要这么做?我该如何阻止它?
答案 0 :(得分:5)
发生这种情况是因为
t_pos = posVec
t_dir = dirVec
您不复制向量的内容但复制其引用。所以基本上 t_pos 和 posVec 指向同一个numpy数组对象。
您想要做的是:
t_pos = numpy.copy(posVec)
t_dir = numpy.copy(dirVec)
编辑:复制方法的差异:
1 import timeit
2 import copy
3 import numpy as np
4
5 someArr = np.arange(100)
6
7 def copy1():
8 tempArr = someArr.copy()
9
10 def copy2():
11 tempArr = np.copy(someArr)
12
13 def copy3():
14 tempArr = copy.copy(someArr)
15
16 def copy4():
17 tempArr = copy.deepcopy(someArr)
18
19 print ("copy1: " + str(timeit.timeit(lambda: copy1(), number=1000000)))
20 print ("copy2: " + str(timeit.timeit(lambda: copy2(), number=1000000)))
21 print ("copy3: " + str(timeit.timeit(lambda: copy3(), number=1000000)))
22 print ("copy4: " + str(timeit.timeit(lambda: copy4(), number=1000000)))
打印以下输出(以秒为单位):
copy1: 0.5677032630010217
copy2: 1.473885050001627
copy3: 1.2420436849988619
copy4: 2.733253653999782
所以是的,存在巨大的差异,但仅限于使用的计算资源。您的示例的结果保持完全相同。
someArr.copy()
指的是你已经保存在内存中的对象,所以访问它是最快的方法,每个numpy数组都有这样的方法,所以基本上你是访问已经创建的numpy数组的方法。 / p>
np.copy(someArr)
调用numpy库的copy-method,因此速度较慢,因为它(据我所知)在创建临时实例时产生了一些开销。
copy.copy(someArr)
是一般复制对象的python(非numpy)方式。我有点困惑,它的表现略好于numpy方式...因为它的普遍性(几乎所有对象)它应该表现得更糟......至少我认为。
copy.deepcopy(someArr)
显然表现最差,但记住它很重要。 Deepcopy不仅可以创建对象的副本(someArr),还可以在数组中创建新的每个元素的新副本。因此,如果您的数组中存储了对象(引用),您将面临同样的问题。因此,使用深度复制,当然不仅要创建数组的副本,而且还要创建其中每个元素的时间。
答案 1 :(得分:1)
您需要复制,您正在引用原始数组,因此其中一个数据的更改将反映在另一个数组中:
t_pos = posVec.copy()
t_dir = dirVec.copy()
您可以使用id函数检查对象的标识:
In [2]: posVec = np.array([0.0,0.0,0.0]) # orginal vectors
In [3]: dirVec = np.array([0.0,0.0,0.0])
In [4]: a = posVec
In [5]: id(a)
Out[5]: 140204693413040
In [6]: id(posVec) # same object so same id
Out[6]: 140204693413040
In [7]: a = posVec.copy()
In [8]: id(posVec)
Out[8]: 140204693413040
In [9]: id(a)
Out[9]: 140204688418096 # new object so new id
你唯一一次被抓住检查id将使用numpy数组的基本索引:
In [10]: posVec = np.array([0.0,0.0,0.0]) # orginal vectors
In [11]: a = posVec[:2]
In [12]: id(a)
Out[12]: 140204688417456
In [13]: id(posVec)
Out[13]: 140204688417776
In [14]: a[0] = 99
In [15]: a
Out[15]: array([ 99., 0.])
In [16]: posVec
Out[16]: array([ 99., 0., 0.])
基本切片返回view 一个不拥有其数据的数组,而是引用另一个数组的数据