什么是乘法运算符实际上与numpy数组做什么?

Kar*_*lek 19 python numpy

我正在学习NumPy,我不确定操作员*实际上在做什么.这似乎是某种形式的乘法,但我不确定它是如何确定的.来自ipython:

In [1]: import numpy as np

In [2]: a=np.array([[1,2,3]])

In [3]: b=np.array([[4],[5],[6]])

In [4]: a*b
Out[4]: 
array([[ 4,  8, 12],
       [ 5, 10, 15],
       [ 6, 12, 18]])

In [5]: b*a
Out[5]: 
array([[ 4,  8, 12],
       [ 5, 10, 15],
       [ 6, 12, 18]])

In [6]: b.dot(a)
Out[6]: 
array([[ 4,  8, 12],
       [ 5, 10, 15],
       [ 6, 12, 18]])

In [7]: a.dot(b)
Out[7]: array([[32]])
Run Code Online (Sandbox Code Playgroud)

看起来它正在进行矩阵乘法,但只是b乘以a,而不是相反.到底是怎么回事?

Vik*_*kez 18

它有点复杂,与广播的概念有关,并且所有numpy操作都是元素明智的.

  1. a是一个包含1行和3列b的2D数组,是一个包含1列和3行的2D数组.
  2. 如果你试图逐个元素地将它们相乘(这是numpy尝试做的事情,a * b因为除了操作之外的每个基本dot操作都是元素的),它必须广播数组,以便它们在所有维度上匹配.
  3. 由于第一阵列是1x3而第二阵列是3x1,因此可以根据广播规则将它们广播为3x3矩阵.它们看起来像:
a = [[1, 2, 3],
     [1, 2, 3],
     [1, 2, 3]]

b = [[4, 4, 4],
     [5, 5, 5],
     [6, 6, 6]]
Run Code Online (Sandbox Code Playgroud)

现在Numpy可以逐个元素地将它们相乘,给你结果:

[[ 4,  8, 12],
 [ 5, 10, 15],
 [ 6, 12, 18]]
Run Code Online (Sandbox Code Playgroud)

在进行.dot操作时,它会执行标准矩阵乘法.更多文档

  • 哦.好.谢谢!应该在跳入之前阅读文档. (4认同)
  • ...也许,也许,对于图书馆作者来说,为了方便起见,重新定义一个核心概念是一个坏主意。 (2认同)

Pav*_*sov 7

* 元素乘法.

由于阵列具有不同的形状,因此将应用广播规则.

In [5]: a.shape
Out[5]: (1, 3)

In [6]: b.shape
Out[6]: (3, 1)

In [7]: (a * b).shape
Out[7]: (3, 3)
Run Code Online (Sandbox Code Playgroud)
  1. 所有输入数组的ndim都小于最大ndim的输入数组,其形状前面有1个(这里不适用).
  2. 输出形状的每个维度的大小是该维度中所有输入大小的最大值.
  3. 如果输入在特定维度中的大小与该维度中的输出大小匹配,或者其值正好为1,则可以在计算中使用该输入.
  4. 如果输入的形状尺寸为1,则该维度中的第一个数据条目将用于沿该维度的所有计算.换句话说,ufunc的步进机械将不会沿着该维度步进(对于该维度,步幅将为0).

因此,生成的形状必须是(3, 3)(最大尺寸ab尺寸大小),并且在执行乘法时numpy不会逐步通过第一个维度和b的第二个维度(它们的大小为1).

结果的[i][j]元素等于广播的元素a和元素的乘积.b[i][j]

(a * b)[0][0] == a[0][0] * b[0][0]
(a * b)[0][1] == a[0][1] * b[0][0]  # (not stepping through b's second dimension)
(a * b)[0][2] == a[0][2] * b[0][0]
(a * b)[1][0] == a[0][0] * b[1][0]  # (not stepping through a's first dimension)

etc.
Run Code Online (Sandbox Code Playgroud)

  • 它起初是,但实际上归结为:如果一个数组的尺寸小于另一个数组,则在它周围抛出另一对括号,直到维数相等.如果任何维度中只有一个元素,则将其用于该维度中的所有索引.如果有多个元素,并且在另一个数组中该维度中有不同数量的元素,则无法执行任何操作并抛出错误. (2认同)