Python arrays are automatically copying each other
我是Python的初学者,我不希望这些数组相互复制,但它们是自动的:
1 2 3 4 | a = numpy.zeros(4) b = a a[1] = 10 print b[1] |
它返回10而不是0。如何断开这两个阵列的连接?
型
"数组自动相互复制"是一个错误的语句,原因有几个。主要原因是您只有一个数组,以及引用该数组的两个变量名。
复制numpy数组有三种方法(即创建与之完全相同的另一个数组):
1 2 3 4 5 6 7 8 9 10 11 12 13 | >>> a = numpy.zeros(4) >>> b = a.copy() >>> c = numpy.copy(a) >>> d = numpy.array(a) >>> a[1] = 10 >>> a array([ 0., 10., 0., 0.]) >>> b array([ 0., 0., 0., 0.]) >>> c array([ 0., 0., 0., 0.]) >>> d array([ 0., 0., 0., 0.]) |
请注意,切片复制(例如
型
您需要一份副本:
1 | b = a.copy() |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | In [5]: a = numpy.zeros(4) In [6]: b = a # reference In [7]: id(a) Out[7]: 140335847505968 In [8]: id(b) # same id's Out[8]: 140335847505968 In [9]: a is b Out[9]: True In [10]: b = a.copy() # new object In [11]: id(a) Out[11]: 140335847505968 In [12]: id(b) # # now different id's Out[12]: 140335437696176 In [13]: a is b # b is no longer pointing to the same memory location Out[13]: False |
号
如果使用基本切片对数组进行切片,则ID将有所不同,但任何更改都将反映在A和B中,因为使用基本索引时,由基本切片生成的所有数组始终是原始数组的视图。视图是一个不拥有其数据的数组,而是引用另一个数组的数据。因此视图是一个新对象,但内容仍然属于原始数组。
但是,使用高级索引高级索引始终返回数据的副本
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | In [141]: a = np.array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) In [142]: b = a[1:7:2] # basic indexing/view In [143]: id(a) Out[143]: 140335437385856 In [144]: id(b) Out[144]: 140335437356528 In [145]: b[0] = 999 In [146]: a Out[146]: array([ 0, 999, 2, 3, 4, 5, 6, 7, 8, 9]) In [148]: b Out[148]: array([999, 3, 5]) In [149]: a = np.array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) In [150]: b = a[[0,3,5]] # advanced indexing/copy In [151]: b Out[151]: array([0, 3, 5]) In [152]: b[0] = 999 In [153]: a Out[153]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) In [154]: b Out[154]: array([999, 3, 5]) In [157]: a = np.array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) In [158]: b = a[a] # copy In [159]: b Out[159]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) In [160]: b[0] = 99 In [161]: a Out[161]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) In [162]: b Out[162]: array([99, 1, 2, 3, 4, 5, 6, 7, 8, 9]) |
这是特定的numpy行为,切片常规的python平面列表将始终创建一个新列表,其中a中的更改不会反映在b中。
1 2 3 4 5 6 7 8 9 10 11 | In [190]: a = [1,2,3,4,5] In [191]: b = a[:3] In [192]: b[0] = 999 In [193]: a Out[193]: [1, 2, 3, 4, 5] In [194]: b Out[194]: [999, 2, 3] |
。
如果列表中包含子列表,并且创建了一个浅副本,则会被python列表捕获:
1 2 3 4 5 6 7 8 9 10 11 | In [197]: a = [[1,2,3],[4,5]] In [198]: b = a[:] In [199]: id(a) Out[199]: 140335437468296 In [200]: id(b) Out[200]: 140335437417992 In [201]: b[0][0] = 999 In [202]: b Out[202]: [[999, 2, 3], [4, 5]] In [203]: a Out[203]: [[999, 2, 3], [4, 5]] |
您需要复制一份.deepcopy:
1 2 3 4 5 6 7 8 | In [204]: a = [[1,2,3],[4,5]] In [205]: from copy import deepcopy In [206]: b = deepcopy(a) In [207]: b[0][0] = 999 In [208]: b Out[208]: [[999, 2, 3], [4, 5]] In [209]: a Out[209]: [[1, 2, 3], [4, 5]] |
。
型
您可以这样使用复制模块
1 2 3 4 5 | from copy import copy a = numpy.zeros(4) b = copy(a) a[1] = 10 print b[1] |
。
这与这样一个事实有关:当您执行
有关此问题的更多信息,请参阅以下答案:如何克隆或复制列表?
型
记住,python中的列表是可变的,这意味着当您执行赋值操作时,它不会创建它的副本,而是复制引用。这意味着两个变量是相同的列表。
您可以这样做,例如:
创建原始列表的副本。
无论如何,我建议您阅读python.org列表部分了解更多信息。