我有包含多维数组的脚本,我想使用矢量化实现来解决我的问题(有时包含列操作)而不是 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)
所以我们有一个 3 行 4 列的矩阵 arr
。
我的脚本中最简单的情况是添加一些东西到数组中的值。例如。我正在对单个或多个行执行此操作:
> 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]])
这很好用。但是,有时我需要操作一个或多个列。一次一列有效:
> 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
但我正在努力思考为什么这对一次多列不起作用:
> 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)
这与处理行的方式不一样吗?我在这里做错了什么?
最佳答案
要将一维数组添加到多个列,您需要 broadcast二维数组的值。由于默认情况下广播会在(形状的)左侧添加新轴,因此会自动将行向量广播到多行:
arr[0:2] += someVector
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]])
someVector
(例如 np.array([1, 2, 3])
)具有形状 (N,)
和 someVector[:, None]
的形状为 (N, 1)
所以现在广播发生在右边。如果 arr[:, 0:2]
的形状为 (N, 2)
,则求和按元素执行,就像 arr[:, 0 :2]
和 someVector[:, None]
是相同形状的数组,(N, 2)
。
关于python - Numpy:一次向量化访问多个列?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35815542/