获取连续副本的习惯用法

idiom for getting contiguous copies

在numpy.broadcst数组的帮助下,引入了一个成语。 但是,该习语给出与原始命令完全相同的输出。 "getting contiguous copies instead of non-contiguous views."是什么意思?

https://docs.scipy.org/doc/numpy/reference/generated/numpy.broadcast_arrays.html

x = np.array([[1,2,3]])
y = np.array([[1],[2],[3]])

np.broadcast_arrays(x, y)
[array([[1, 2, 3],
       [1, 2, 3],
       [1, 2, 3]]), array([[1, 1, 1],
       [2, 2, 2],
       [3, 3, 3]])]

这是获取连续副本而不是非连续视图的有用习惯用法。

[np.array(a) for a in np.broadcast_arrays(x, y)]

[array([[1, 2, 3],
       [1, 2, 3],
       [1, 2, 3]]), array([[1, 1, 1],
       [2, 2, 2],
       [3, 3, 3]])]

要了解差异,请尝试写入新数组:

让我们从连续的副本开始。

>>> import numpy as np
>>> x = np.array([[1,2,3]])
>>> y = np.array([[1],[2],[3]])
>>> 
>>> xc, yc = [np.array(a) for a in np.broadcast_arrays(x, y)]
>>> xc
array([[1, 2, 3],
       [1, 2, 3],
       [1, 2, 3]])

我们可以修改一个元素,不会发生任何意外。

>>> xc[0, 0] = 0
>>> xc
array([[0, 2, 3],
       [1, 2, 3],                                                                                                   
       [1, 2, 3]])
>>> x
array([[1, 2, 3]])

现在,让我们对广播数组进行同样的尝试:

>>> xb, yb = np.broadcast_arrays(x, y)
>>> xb
array([[1, 2, 3],
       [1, 2, 3],
       [1, 2, 3]])

虽然我们只写入左上角的元素...

>>> xb[0, 0] = 0

...整个左栏都会改变...

>>> xb
array([[0, 2, 3],
       [0, 2, 3],
       [0, 2, 3]])

...还有输入数组。

>>> x
array([[0, 2, 3]])

这意味着 broadcast_arrays 函数不会创建全新的对象。它从原始数组创建视图,这意味着它的结果元素具有内存地址,因为这些数组可能是连续的,也可能不是连续的。但是当你创建一个列表时,你是在列表中创建新的副本,这保证了它的项目在内存中是连续存储的。

您可以像下面这样检查:

arr = np.broadcast_arrays(x, y)
In [144]: arr
Out[144]: 
[array([[1, 2, 3],
        [1, 2, 3],
        [1, 2, 3]]), array([[1, 1, 1],
        [2, 2, 2],
        [3, 3, 3]])]

In [145]: x
Out[145]: array([[1, 2, 3]])

In [146]: arr[0][0] = 0

In [147]: arr
Out[147]: 
[array([[0, 0, 0],
        [0, 0, 0],
        [0, 0, 0]]), array([[1, 1, 1],
        [2, 2, 2],
        [3, 3, 3]])]

In [148]: x
Out[148]: array([[0, 0, 0]])

如您所见,更改 arr 的元素会同时更改其元素和原始 x 数组。