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

时间:2019-05-21 05:33:13

标签: python numpy multidimensional-array deep-copy

据我所知,ndarray的深层副本应创建ndarray的第二次迭代,以便更改其中一个数组不会影响另一个的内容。但是,在下面的代码中,我原来的ndarray被更改了:

Game::Game() : mWindow(sf::VideoMode(640, 480), "Pong Game")
{}

void Game::Run()
{
    while(mWindow.isOpen())
    {
        sf::Event e;
        while(mWindow.pollEvent(e))
        {
            if(e.type == sf::Event::Closed)
            {
                mWindow.close();
            }
        }
    }
}

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

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']

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

np.shares_memory(new, data) #false

np.might_share_memory(new,data) #false

2 个答案:

答案 0 :(得分:4)

您应该使用copy's deepcopy,[:]不会进行深度复制:

In [11]: a = [[1], 2]

In [12]: b = a[:]

In [13]: from copy import deepcopy
    ...: c = deepcopy(a)

In [14]: b[0].append(3)

In [15]: a
Out[15]: [[1, 3], 2]

In [16]: c
Out[16]: [[1], 2]

答案 1 :(得分:4)

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

您尝试进行深复制的情况:

data

不是深层副本。对于大多数普通数组而言,它将是一个副本(对于大多数数组而言,深/浅等效),但对于列表而言,则不是深副本,而对于object-dtype数组,则不是深副本。它将创建一个新的object-dtype数组,并用对new = np.empty_like(data) new[:] = data 单元格所引用的相同对象的引用进行填充。

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