dan*_*451 4 python arrays numpy vectorization slice
我有多维数组的脚本而不是for循环我想为我的问题使用矢量化实现(有时包含列操作).
让我们考虑一个矩阵的简单示例arr:
> arr = np.arange(12).reshape(3, 4)
> arr
> ([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]])
> arr.shape
> (3, 4)
Run Code Online (Sandbox Code Playgroud)
所以我们有一个arr3行4列的矩阵.
我的脚本中最简单的情况是向数组中的值添加内容.例如,我正在为单行或多行执行此操作:
> someVector = np.array([1, 2, 3, 4])
> arr[0] += someVector
> arr
> array([[ 1, 3, 5, 7], <--- successfully added someVector
[ 4, 5, 6, 7], to one row
[ 8, 9, 10, 11]])
> arr[0:2] += someVector
> arr
> array([[ 2, 5, 8, 11], <--- added someVector to two
[ 5, 7, 9, 11], <--- rows at once
[ 8, 9, 10, 11]])
Run Code Online (Sandbox Code Playgroud)
这很好用.但是,有时我需要操纵一个或多个列.一列一栏有效:
> arr[:, 0] += [1, 2, 3]
> array([[ 3, 5, 8, 11],
[ 7, 7, 9, 11],
[11, 9, 10, 11]])
^
|___ added the values [1, 2, 3] successfully to
this column
Run Code Online (Sandbox Code Playgroud)
但我正在努力思考为什么这对多个列不起作用:
> arr[:, 0:2] += [1, 2, 3]
> ValueError
> Traceback (most recent call last)
> <ipython-input-16-5feef53e53af> in <module>()
> ----> 1 arr[:, 0:2] += [1, 2, 3]
> ValueError: operands could not be broadcast
> together with shapes (3,2) (3,) (3,2)
Run Code Online (Sandbox Code Playgroud)
这与行合作的方式不一样吗?我在这做错了什么?
要将1D数组添加到多个列,您需要将值广播到2D数组.由于广播默认在左侧(形状)添加新轴,因此自动将行向量广播到多行:
arr[0:2] += someVector
Run Code Online (Sandbox Code Playgroud)
someVector有形状(N,),并自动播放形状(1, N).如果arr[0:2]有形状(2, N),则总和进行逐元素好像两者arr[0:2]和someVector是相同形状的阵列,(2, N).
但是要将列向量广播到多个列,需要提示NumPy,您希望广播与右侧的轴一起发生.实际上,您必须通过使用someVector[:, np.newaxis]或等效地在右侧添加新轴someVector[:, None]:
In [41]: arr = np.arange(12).reshape(3, 4)
In [42]: arr[:, 0:2] += np.array([1, 2, 3])[:, None]
In [43]: arr
Out[43]:
array([[ 1, 2, 2, 3],
[ 6, 7, 6, 7],
[11, 12, 10, 11]])
Run Code Online (Sandbox Code Playgroud)
someVector(例如np.array([1, 2, 3]))具有形状(N,)和someVector[:, None]形状,(N, 1)所以现在广播发生在右边.如果arr[:, 0:2]有形状(N, 2),则总和进行逐元素好像两者arr[:, 0:2]和someVector[:, None]是相同形状的阵列,(N, 2).
@unutbu非常明确的解释.
作为补充,transposition(.T)通常可以通过在第一维中工作来简化任务:
In [273]: arr = np.arange(12).reshape(3, 4)
In [274]: arr.T[0:2] += [1, 2, 3]
In [275]: arr
Out[275]:
array([[ 1, 2, 2, 3],
[ 6, 7, 6, 7],
[11, 12, 10, 11]])
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
346 次 |
| 最近记录: |