高级切片:Python列表与Numpy数组

时间:2019-01-22 15:23:55

标签: python arrays numpy

我想交换二维数组中的行。为此,使用高级切片非常方便:

In [50]: l
Out[50]: [[0, 1], [2, 3], [4, 5], [6, 7]]

In [51]: l[::2], l[1::2] = l[1::2], l[::2]

In [52]: l
Out[52]: [[2, 3], [0, 1], [6, 7], [4, 5]]

但是,如果我将列表转换为Numpy数组,这将不起作用:

In [60]: arr
Out[60]: 
array([[0, 1],
       [2, 3],
       [4, 5],
       [6, 7]])

In [61]: arr[::2], arr[1::2] = arr[1::2], arr[::2]

In [62]: arr
Out[62]: 
array([[2, 3],
       [2, 3],
       [6, 7],
       [6, 7]])

为什么这种交换方法不适用于Numpy数组?

1 个答案:

答案 0 :(得分:3)

  

为什么这种交换方法不适用于numpy数组?

简而言之:Numpy数组是真正的多维对象,并提供数据上的 views 。 Python list对象不是。

您只会用l[...]索引一个列表,而永远不会嵌套{em}和独立 list对象的内容。切片还会生成 new 列表对象,并引用复制到切片结果中的嵌套列表。

另一方面,

Numpy切片可处理整个矩阵中的单个单元格和一系列单元格,并为您提供数据上的视图;您可以更改numpy数组切片的结果,并查看反映在原始数组中的更改。

后者是您在这里出问题的地方;当您将第二行分配给第一行的单元格时,对第一行单元格的引用随赋值更改,因为它们不是副本,而是视图,并且您最终将第二行单元格通过第一行复制回第二行。

因此,如果要交换numpy数组中的行,请you'll have to create a copy first

source = arr.copy()
arr[::2], arr[1::2] = source[1::2], source[::2]