为什么索引一个Numpy列会创建一个副本,而不为行或一维数组创建一个副本?

时间:2020-04-02 20:39:05

标签: python arrays numpy multidimensional-array syntax

所以说我有一个名为array1D的数组:

array1D

array([0, 1, 2, 3, 4, 5])

然后我将其切成薄片并将其值分配给22

slice_of_array1D = array1D[0:3]
slice_of_array1D[:] = 22

如果我检查切片的原始数组,则前3个值也将更改为22

array1D

array([22, 22, 22,  3,  4,  5])

现在,我知道这样做是为了节省内存,因为slice_of_array1D仅引用array1D而不是创建副本,而这需要使用array1D.copy()。但是,令我感到困惑的是为什么它对矩阵列也没有这样做?这是一个示例:

array2D

array([[1, 2, 3],
       [4, 5, 6],
       [7, 8, 9]])

现在让我们从第一列的array2D切片开始,并对其进行调用以显示其外观:

slice_of_array2D = array2D[:,[0]]

slice_of_array2D

array([[1],
       [4],
       [7]])

现在让我们将切片的值分配为22,调用切片,然后调用原始的array2D

slice_of_array2D[:] = 22

slice_of_array2D

array([[22],
       [22],
       [22]])

array2D

array([[1, 2, 3],
       [4, 5, 6],
       [7, 8, 9]])

看看原始的array2D如何保持不变?为什么会这样。像对一维数组一样,对行而不是对列执行此操作会更改原始矩阵中的值。但是,正如您在上面看到的,列似乎是不受干扰的。现在,在Python中是否有理由/理由?我问是因为我正在学习使用Python / Numpy而不是MATLAB来使用它,所以我的大部分工作将使用矩阵和线性代数等。我希望逻辑上可以证明这样做的理由,也就是了解Python / Numpy是如何思考的”,这样我可以更轻松地使用它。

谢谢你的朋友们!对于很长的问题,我深表歉意,但我想提供所有可能相关的信息:)

1 个答案:

答案 0 :(得分:1)

这里只是索引选项的一个示例:

In [431]: arr = np.arange(1,13).reshape(3,4)                                                   
In [432]: arr                                                                                  
Out[432]: 
array([[ 1,  2,  3,  4],
       [ 5,  6,  7,  8],
       [ 9, 10, 11, 12]])

带有标量的索引会减小尺寸:

In [433]: arr[1]                                                                               
Out[433]: array([5, 6, 7, 8])      # (4,)
In [434]: arr[:,1]                                                                             
Out[434]: array([ 2,  6, 10])      # (3,)

那些元素仍然可以访问:

In [435]: arr[:,1] +=10                                                                        
In [436]: arr                                                                                  
Out[436]: 
array([[ 1, 12,  3,  4],
       [ 5, 16,  7,  8],
       [ 9, 20, 11, 12]])

带有列表的索引会保留维度:

In [437]: arr[:,[1]]                                                                           
Out[437]:                 # (3,1) 
array([[12],
       [16],
       [20]])
In [438]: arr[[1]]                                                                             
Out[438]: array([[ 5, 16,  7,  8]])     # (1,3)

索引,其中包含多个项目的列表;尾随的:是可选的:

In [439]: arr[[1,2],:]                                                                         
Out[439]: 
array([[ 5, 16,  7,  8],
       [ 9, 20, 11, 12]])

具有多个数组的索引-这是一个类似“对角线”的选择(在MATLAB中很难做到):

In [440]: arr[[1,2],[1,2]]                                                                     
Out[440]: array([16, 11])

这里是一个块选择(典型的MATLAB):

In [441]: arr[[[1],[2]],[1,2]]                                                                 
Out[441]: 
array([[16,  7],
       [20, 11]])

与切片相同的选择(视图):

In [442]: arr[1:3,1:3]                                                                         
Out[442]: 
array([[16,  7],
       [20, 11]])