【问题标题】:Slicing a NumPy array within a loop [duplicate]在循环中切片 NumPy 数组[重复]
【发布时间】:2016-07-03 12:32:21
【问题描述】:

我需要一个很好的解释(参考)来解释(for)循环中的 NumPy 切片。我有三个案例。

def example1(array):
    for row in array:
        row = row + 1
    return array

def example2(array):
    for row in array:
        row += 1
    return array

def example3(array):
    for row in array:
        row[:] = row + 1
    return array

一个简单的案例:

ex1 = np.arange(9).reshape(3, 3)
ex2 = ex1.copy()
ex3 = ex1.copy()

返回:

>>> example1(ex1)
array([[0, 1, 2],
       [3, 4, 5],
       [6, 7, 8]])

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

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

可以看出,第一个结果与第二个和第三个不同。

【问题讨论】:

标签: python arrays numpy


【解决方案1】:

第一个例子:

您提取一行并将其加 1。然后你重新定义 指针 row 但不是array 包含的内容!所以不会影响原数组。

第二个例子:

您进行就地操作 - 显然这会影响原始数组 - 只要它是一个数组。

如果你在做一个双循环,它就不再起作用了:

def example4(array):
    for row in array:
        for column in row:
            column += 1
    return array

example4(np.arange(9).reshape(3,3))
array([[0, 1, 2],
       [3, 4, 5],
       [6, 7, 8]])

这不起作用,因为您不调用np.ndarray__iadd__(修改数组指向的数据)而是调用python int__iadd__。因此,此示例仅适用于您的行是 numpy 数组。

第三个例子:

row[:] = row + 1 这被解释为类似row[0] = row[0]+1, row[1] = row[1]+1, ... 的东西,这又在原地工作,所以这会影响原始数组。

底线

如果您对可变对象进行操作,例如lists 或np.ndarray,您需要小心您所做的更改。这样的对象仅指向实际数据存储在内存中的位置 - 因此更改此 指针 (example1) 不会影响保存的数据。您需要按照指针(直接通过[:] (example3) 或间接通过array.__iadd__ (example2))更改保存的数据。

【讨论】:

    【解决方案2】:

    在第一个代码中,您不对新的计算行做任何事情;您重新绑定名称row,并且不再与阵列连接。

    在第二个和第三个中,您不重新绑定,而是将值分配给旧变量。使用+= 会调用一些内部函数,这取决于您让它作用的对象的类型。请参阅下面的链接。

    如果您在右侧写row + 1,则会计算一个新数组。在第一种情况下,您告诉 python 给它 name row(忘记之前称为 row 的原始对象)。第三步,将新数组写入旧row 的切片中。

    如需进一步阅读,请点击上面@Thiru 对问题的评论链接。或阅读assignment and rebinding in general...

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-08-06
      • 2023-03-03
      • 1970-01-01
      • 2014-12-15
      • 1970-01-01
      • 1970-01-01
      • 2012-02-20
      相关资源
      最近更新 更多