获取连续副本的习惯用法
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
数组。
在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
数组。