乐趣区

关于python:Python详解Numpy中的点积运算

  1. 引言
    依据数学家的说法,点积是一种运算,它取两个等长的向量作为输出,而后返回一个数字(标量)。向量 A 与向量 B 的点积用符号示意为 A•B。在线性代数中,点积是输出向量中每个对应元素的乘积之和。
    本文重点介绍点积的定义以及相干代码实现,闲话少说,咱们间接开始吧!
  2. 举个栗子
    考虑一下咱们去商店购买货品的购物单,如下所示:
Item    | Quantity | Unit Cost
Wine    | 2        | 12.50
Orange  | 12       | 0.50
Muffin  | 3        | 1.75

假如咱们须要计算咱们的购物账单,此时咱们须要失去每件商品的老本,而后把它们加起来。要计算每个我的项目的单个老本,咱们须要将该项目标数量乘以其单位价格即可。换句话说,咱们须要进行的运算为(212.50)+(120.5)+(3*1.75)=36.25。上述操作被称为加权和。

此外,如果咱们将数量和单位价格示意为两个向量,咱们也能够将加权和示意为点积的模式。如下所示:

quantity = [2,12,3]
costs    = [12.5,.5,1.75]
sum(q*c for q,c in zip(quantity,costs))

上述代码中的点积运算等价于所有物品的单价乘以对应数量求和后失去的总和。

  1. 应用 Numpy 中的点积
    同样的操作也能够在 NumPy 中实现,并取得较好的运行性能。
    样例代码如下:

    import numpy as np
    quantity = np.array([2,12,3])
    costs    = np.array([12.5,.5,1.75])
    np.sum(quantity*costs) # element-wise multiplication
    

    应用 NumPy 进行求和的形式更加简略。能够用三种不同的形式实现。

quantity.dot(costs)    # dot product way 1
np.dot(quantity,costs) # dot product way 2
quantity @ costs       # dot product way 3
  1. 一维数组运算
    在 Python 中解决行与列相乘时须要特地小心。咱们无妨思考以下二维数组​​row_vec ​​和​​col_vec​​,如下所示:
row_vec = np.arange(5).reshape(1,5)
col_vec = np.arange(0,50,10).reshape(5,1)
Outputs are:
row_vec = 
array([[0, 1, 2, 3, 4]])
col_vec = 
array([[0],
       [10],
       [20],
       [30],
       [40]])

如果咱们应用内积进行计算,输入如下:

out = np.dot(row_vec, col_vec)
Output is:
array([[300]]

然而如果咱们将二者进行调换呢?输入如下:

out = np.dot(col_vec, row_vec)
Output is:
array([[0,   0,   0,   0,   0],
       [0,  10,  20,  30,  40],
       [0,  20,  40,  60,  80],
       [0,  30,  60,  90, 120],
       [0,  40,  80, 120, 160]])

显然,​​col_vecrow_vec​​与​​row_veccol_vec​​的输入是不一样的!咱们当初有一个 5 行 5 列的矩阵,而不再是一个数字。让咱们看看后果中任一个元素,看看它来自哪里。回忆一下,在 Python 中,第一个索引是 0。咱们思考元素​​out[1,2]​​,此值为 20。它来自​​col_vec​​第 1 行与​​row_vec ​​的第 2 列两个向量的点积,将两者相乘失去后果 20。

  1. 一维数组和二维数组点积运算
    当咱们把一维数组和二维数组联合起来进行点击运算时,咱们应该更加小心。
oned_vec = np.arange(5) # output is array([0, 1, 2, 3, 4])
row_vec = np.arange(5).reshape(1,5)
col_vec = np.arange(0,50,10).reshape(5,1)
np.dot(oned_vec, col_vec) # output is array([300])
np.dot(row_vec, oned_vec) # output is array([30])

然而,如果咱们替换相应的秩序,代码可能无奈失常运行!

np.dot(col_vec, oned_vec)
np.dot(oned_vec, row_vec)
Output:
shapes (5,1) and (5,) not aligned: 1 (dim 1) != 5 (dim 0)
shapes (5,) and (1,5) not aligned: 5 (dim 0) != 1 (dim 0)

从上述谬误音讯中,咱们能够看到​​col_vec​​的 shape 为(5,1),​​row_vec​​对应的 shpae 为(1,5),而​​oned_vec​​对应的 shape 为(5,)。咱们晓得两个数组进行点积运算,第一个数组的列数应该等于第二个数组的行数,所以上述代码会显式地报下面的错误信息。同时上述代码阐明,如果将一个一维的数组放到​​np.dot()​​第一个参数地位,则此时​​oned_vec​​将被当做 shape 为(1,5)的数组,同时如果将其放到​​np.dot()​​的第二个参数地位,则此时​​oned_vec​​将被当做 shape 为(5,1)的数组。

  1. 多维数组点积运算
    NumPy 还容许咱们创立具备多个值输入的数组,而不仅仅是一个值。这取决于输出数组的形态,如下所示:
D = np.array([[1,3],[2,5],[2,7],[3,2]])
w = np.array([1.5,2.5])
np.dot(D,w) # [9,15.5,20.5,9.5]

通过上述示例,咱们能够看出,​​1.51+2.53=9​​顺次类推。这里,因为 w 在左边,所以它能够视为 2 行 1 列的数组。咱们用一个 4 行 2 列的数组乘以一个 2 行 1 列的数组,将产生一个蕴含 4 个元素的一维数组。

  1. 总结
    本文重点介绍了 Numpy 中点积的定义,以及相应的运算,并给出了相应的代码示例。
退出移动版