我正在创建一个numpy数组列表,然后将其复制到另一个数组中,以保存原始副本。使用deepcopy()函数完成复制。当我现在比较这两个数组时,它在等价性上是错误的。但是,当我使用copy()函数时,.I理解了复制函数和深度复制函数之间的区别,但其等价性是否是相同的呢?
这就是:
grid1=np.empty([3,3],dtype=object)
for i in xrange(3):
for j in xrange(3):
grid1[i][j] = [i,np.random.uniform(-3.5,3.5,(3,3))]
grid_init=[]
grid_init=copy.deepcopy(grid1)
grid1==grid_init #returns False
grid_init=[]
grid_init=copy.copy(grid1)
grid1==grid_init #returns True
grid_init=[]
grid_init=copy.deepcopy(grid1)
np.array_equal(grid1,grid_init) #returns False难道一切都不是真的吗?
发布于 2016-01-16 07:42:16
我一定在运行numpy/python的不同版本,但是我得到的错误和/或结果略有不同。同样的问题也同样适用--混合数组和列表会产生复杂的结果。
复制这两份
In [217]: x=copy.copy(grid1)
In [218]: y=copy.deepcopy(grid1)与浅拷贝相等,给出一个逐元素比较的元素,一个3x3布尔值:
In [219]: x==grid1
Out[219]:
array([[ True, True, True],
[ True, True, True],
[ True, True, True]], dtype=bool)元素是两个项目列表:
In [220]: grid1[0,0]
Out[220]:
[0, array([[ 2.08833787, -0.24595155, -3.15694342],
[-3.05157909, 1.83814619, -0.78387624],
[ 1.70892355, -0.87361521, -0.83255383]])]在浅拷贝中,列表in是相同的。这两个数组具有不同的数据缓冲区(x不是视图),但它们都指向相同的列表对象(位于记忆中的其他位置)。
In [221]: id(grid1[0,0])
Out[221]: 2958477004
In [222]: id(x[0,0])
Out[222]: 2958477004对于相同的id,列表是相等的(它们还满足is测试)。
In [234]: grid1[0,0]==x[0,0]
Out[234]: True但是,带有深度拷贝的==产生了一个简单的False。这里没有逐个元素的比较。我不知道为什么。也许这是numpy正在开发的一个领域。
In [223]: y==grid1
Out[223]: False请注意,深度复制元素ids是不同的:
In [229]: id(y[0,0])
Out[229]: 2957009900当我试图将==应用于这些数组的一个元素时,我会得到一个错误:
In [235]: grid1[0,0]==y[0,0]
...
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()这是在这样的问题中反复出现的错误,通常是因为人们试图在标量Python上下文中使用布尔数组(来自比较)。
我可以将数组与列表中的数组进行比较:
In [236]: grid1[0,0][1]==y[0,0][1]
Out[236]:
array([[ True, True, True],
[ True, True, True],
[ True, True, True]], dtype=bool)我可以使用更简单的比较-2列表来再现ValueError,其中包含一个数组。表面上,它们看起来是一样的,但是由于数组有不同的it,所以失败了。
In [239]: [0,np.arange(3)]==[0,np.arange(3)]
...
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()这对比较显示了正在发生的事情:
In [242]: [0,np.arange(3)][0]==[0,np.arange(3)][0]
Out[242]: True
In [243]: [0,np.arange(3)][1]==[0,np.arange(3)][1]
Out[243]: array([ True, True, True], dtype=bool)Python比较列表的各个元素,然后尝试执行逻辑操作来组合它们,即all()。但是它不能在all上执行[True, array([True,True,True])]。
因此,在我的版本中,y==grid1返回False,因为元素逐元素比较返回ValueErrors。否则就会产生错误或警告。他们显然不平等。
总之,使用此数组的数字和数组,等式测试结束混合数组操作和列表操作。结果是合乎逻辑的,但很复杂。您必须敏锐地了解数组是如何比较的,列表是如何比较的。它们是不可互换的。
结构化数组
您可以将这些数据放入结构化数组中,使用类似于dtype的
dt = np.dtype([('f0',int),('f1',float,(3,3))])
In [263]: dt = np.dtype([('f0',int),('f1',float,(3,3))])
In [264]: grid2=np.empty([3,3],dtype=dt)
In [265]: for i in range(3):
for j in range(3):
grid2[i][j] = (i,np.random.uniform(-3.5,3.5,(3,3)))
.....:
In [266]: grid2
Out[266]:
array([[ (0,
[[2.719807845330254, -0.6379512247418969, -0.02567206509563602],
[0.9585030371031278, -1.0042751112999135, -2.7805349057485946],
[-2.244526250770717, 0.5740647379258945, 0.29076071288760574]]),
....]])]],
dtype=[('f0', '<i4'), ('f1', '<f8', (3, 3))])第一个字段,整数可以用(给出一个3x3数组)。
In [267]: grid2['f0']
Out[267]:
array([[0, 0, 0],
[1, 1, 1],
[2, 2, 2]])第二个字段包含3x3数组,当按字段名访问时,这些数组是一个4d数组:
In [269]: grid2['f1'].shape
Out[269]: (3, 3, 3, 3)单个元素是记录(或元组),
In [270]: grid2[2,1]
Out[270]: (2, [[1.6236266210555836, -2.7383730706629636, -0.46604477485902374], [-2.781740733659544, 0.7822732671353201, 3.0054266762730473], [3.3135671425199824, -2.7466097112667103, -0.15205961855874406]])现在这两种拷贝产生的东西是一样的:
In [271]: x=copy.copy(grid2)
In [272]: y=copy.deepcopy(grid2)
In [273]: x==grid2
Out[273]:
array([[ True, True, True],
[ True, True, True],
[ True, True, True]], dtype=bool)
In [274]: y==grid2
Out[274]:
array([[ True, True, True],
[ True, True, True],
[ True, True, True]], dtype=bool)由于grid2是纯ndarray (没有中间列表),我怀疑copy.copy和copy.deepcopy最终使用了grid2.copy()。在numpy中,我们通常使用数组复制方法,而不必费心使用copy模块。
附注:使用dtype=object,grid1.copy()似乎与copy.copy(grid1)相同--一个新的数组,但对象指针相同(即相同的数据)。
发布于 2016-01-16 06:24:32
这就是我在运行第一个示例时得到的结果:
WARNING:py.warnings:/usr/local/bin/ipython:1: DeprecationWarning: elementwise comparison failed; this will raise the error in the future.要了解元素级比较失败的原因,只需尝试比较单个元素:
grid_init=copy.deepcopy(grid1)
grid_init[0][0] == grid1[0][0]
>>> ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()这是因为列表中的第二个元素本身就是numpy数组,而比较两个numpy数组并不返回bool (而是一个数组)。
那么,为什么这个例子表现得不同呢?
似乎是一些解释器优化,避免了实际的比较逻辑,如果这两个对象是相同的。这两个对象是同一个对象,因为复制比较浅。
grid_init=copy.copy(grid1)
grid_init[0][0] is grid1[0][0]
> True
grid_init[0][0] == grid1[0][0]
> True根本原因是您使用的是--一个dtype=object的numpy数组,其中包含了中的列表。这不是一个好主意,并可能导致各种怪胎。
相反,您应该创建2个对齐数组,一个用于列表中的第一个元素,另一个用于第二个元素。
https://stackoverflow.com/questions/34824110
复制相似问题