带副本的numpy数组分配


103

例如,如果我们有一个numpyarray A,我们想要一个numpy数组B具有相同元素。

以下(见下文)方法之间的区别是什么?什么时候分配额外的内存,什么时候不分配?

  1. B = A
  2. B[:] = A(与B[:]=A[:]?相同)
  3. numpy.copy(B, A)

Answers:


127

这三个版本都做不同的事情:

  1. B = A

    这会将新名称绑定B到已经命名的现有对象A。之后,它们引用同一个对象,因此,如果您就地修改一个对象,那么您也会在另一个对象中看到更改。

  2. B[:] = A(与B[:]=A[:]?相同)

    这会将值从中复制A到现有数组中B。两个数组必须具有相同的形状才能起作用。B[:] = A[:]做同样的事情(但B = A[:]会做更多类似1的事情)。

  3. numpy.copy(B, A)

    这不是合法的语法。你可能是说B = numpy.copy(A)。这几乎与2相同,但是它创建了一个新数组,而不是重用该B数组。如果没有其他对先前B值的引用,则最终结果将与2相同,但是在复制期间它将临时使用更多内存。

    也许您是说numpy.copyto(B, A),这是合法的,等于2?


21
@Mr_and_Mrs_D:Numpy数组的工作方式不同于列表。切片数组不会复制,它只是在现有数组的数据上创建一个新视图。
Blckknght

什么意思but B = A[:] would do something more like 1?根据此stackoverflow.com/a/2612815 new_list = old_list[:]也是副本。
mrgloom

4
@mrgloom:在分割和复制其内容时,numpy数组的工作方式与列表不同。数组是存储数值的基础内存块的“视图”。像这样进行切片some_array[:]将创建一个新的数组对象,但是该新对象将是与原始数组相同内存的视图,该内存不会被复制。这就是为什么我说它更像是B = A。它仅占用O(1)空间和时间,而不O(n)需要真正副本所需的时间和空间。
Blckknght

27
  1. B=A 创建参考
  2. B[:]=A 复制
  3. numpy.copy(B,A) 复制

后两个需要额外的内存。

要制作深拷贝,您需要使用 B = copy.deepcopy(A)


2
关于你第二个例子:B[:] = A使对象类型,例如数组的深层副本A = np.array([[1,2,3],[4,5]]); B = np.array([None,None], dtype='O')。现在尝试B[:] = A; B[0][0]=99,这将同时更改A和B中的第一个元素!据我所知,没有其他方法可以保证深度复制,甚至是一个numpy数组,也只能保证copy.deepcopy
Rolf Bartstra

11

这是我唯一的工作答案:

B=numpy.array(A)
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.