【问题标题】:Advanced slicing: Python lists vs Numpy arrays [duplicate]高级切片:Python 列表与 Numpy 数组 [重复]
【发布时间】:2019-06-16 02:38:41
【问题描述】:

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

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 数组?

【问题讨论】:

  • 您是在问为什么 Numpy 数组处理切片的方式不同,还是希望在使用 Numpy 数组时获得相同的结果? 为什么不是一个很有用的问题,而且太宽泛,无法在这里回答。
  • 怎么样? l = 列表(arr); l[::2], l[1::2] = l[1::2], l[::2]; arr = np.array(l);
  • @MartijnPieters:我在问为什么这种特殊的交换方法对列表有效,而对 numpy 数组无效。为什么这意味着“为什么他们的行为不同”。
  • @DmytroPrylipko:广泛的答案是 numpy 数组不是列表。它们是矩阵并支持更丰富的索引语法。 Python 列表是一维的野兽,列表中有列表对象,因此您只处理最外层的列表。 Numpy 数组是真正的多维矩阵,不仅对行进行切片。

标签: python arrays numpy


【解决方案1】:

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

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

您只能用l[...] 索引一个 列表,而不是嵌套和独立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]

【讨论】:

  • 这就是我如此喜欢的原因。您真的可以了解语言的内部结构。
猜你喜欢
  • 1970-01-01
  • 2016-12-28
  • 2023-03-28
  • 2020-12-11
  • 2011-08-30
  • 2021-12-31
  • 1970-01-01
  • 1970-01-01
  • 2015-05-09
相关资源
最近更新 更多