顽皮的深拷贝仍在改变原始数组

Bob*_*win 5 python numpy deep-copy multidimensional-array

据我了解,一个ndarray的深拷贝应该创建ndarray的第二次迭代,以便更改其中一个数组不会影响另一个数组的内容。但是,在以下代码中,我原来的ndarray发生了变化:

print(data[3])   #[array([[0.00000000e+00, 3.29530000e+04],
   #[4.00066376e-04, 3.29530000e+04],
   #[8.00132751e-04, 3.29530000e+04],
   #...,
   #[1.28784461e+03, 3.47140000e+04],
   #[1.28784621e+03, 3.57750000e+04],
   #[1.28785381e+03, 1.92450000e+04]]),
   #'CH4.VDC1']

new = np.empty_like(data)
new[:] = data
new[3][0][:,1] = 4/16421 * (data[3][0][:,1] - 33563)

print(data[3])  #[array([[ 0.00000000e+00, -1.48590220e-01],
   #[ 4.00066376e-04, -1.48590220e-01],
   #[ 8.00132751e-04, -1.48590220e-01],
   #...,
   #[ 1.28784461e+03,  2.80372694e-01],
   #[ 1.28784621e+03,  5.38822240e-01],
   #[ 1.28785381e+03, -3.48772913e+00]]),
   #'CH4.VDC1']
Run Code Online (Sandbox Code Playgroud)

该数组是混合类型(5,2)数组,其中包含(largenumber,2)子数组。我只是想更改子数组,但我想知道深拷贝是否也扩展到该子数组。我跑了

np.shares_memory(new, data) #false

np.might_share_memory(new,data) #false
Run Code Online (Sandbox Code Playgroud)

可能还需要注意的是,我正在jupyter笔记本中运行此程序。虽然我无法想象为什么它会改变任何东西。您可以使用以下方法重新创建数据:

np.array([[[[0.00000000e+00, 2.82540000e+04],
[4.00066376e-04, 2.82530000e+04],
[8.00132751e-04, 2.82520000e+04],
[1.28784461e+03, 4.61170000e+04],
[1.28784621e+03, 3.38280000e+04],
[1.28785381e+03, 3.38230000e+04]],
'CH1.Bx'],
[[[0.00000000e+00, 2.00400000e+04],
[4.00066376e-04, 2.00400000e+04],
[8.00132751e-04, 2.00410000e+04],
[1.28784461e+03, 1.81600000e+04],
[1.28784621e+03, 1.80830000e+04],
[1.28785381e+03, 4.80200000e+03]],
'CH2.By'],
[array([[0.00000000e+00, 3.82520000e+04],
[4.00066376e-04, 3.82510000e+04],
[8.00132751e-04, 3.82510000e+04],
[1.28784461e+03, 3.42810000e+04],
[1.28784621e+03, 3.42820000e+04],
[1.28785381e+03, 3.40380000e+04]]),
'CH3.Bz'],
[[[ 0.00000000e+00, -1.48590220e-01],
[ 4.00066376e-04, -1.48590220e-01],
[ 8.00132751e-04, -1.48590220e-01],
[ 1.28784461e+03,  2.80372694e-01],
[ 1.28784621e+03,  5.38822240e-01],
[ 1.28785381e+03, -3.48772913e+00]],
'CH4.VDC1'],
[[[0.00000000e+00, 3.26760000e+04],
[4.00066376e-04, 3.26760000e+04],
[8.00132751e-04, 3.26750000e+04],
[1.28784981e+03, 3.40450000e+04],
[1.28785061e+03, 3.40420000e+04],
[1.28785141e+03, 3.40390000e+04]],
'CH5.VDC2']], dtype=object)`
Run Code Online (Sandbox Code Playgroud)

use*_*ica 4

这看起来不像是您从那里开始的数组。目前还不清楚是什么data,但data[3]它是一个包含数组和字符串的 2 元素列表,据此判断,data可能是另一个列表,或者可能是一个 object-dtype 数组。

您尝试进行深层复制:

new = np.empty_like(data)
new[:] = data
Run Code Online (Sandbox Code Playgroud)

不是深拷贝。对于大多数普通数组来说,它是一个副本(对于大多数数组来说,深/浅是等效的),但不是列表的深副本,也不是对象数据类型数组的深副本。它将创建一个新的 object-dtype 数组,并用对 的单元格所引用的相同对象的引用来填充它data

您可能应该选择一种更好的方式来组织数据。这种数据结构并不是使用 NumPy 的有效方式,而且它会导致更多的问题。也就是说,如果您想深度复制它,copy.deepcopy这可能是您最好的选择。