细说NumPy数组的四种乘法的使用

当孔乙己说回字有四样写法的时候,相信各位都是这样的表情吧?

但是,如果孔乙己说NumPy数组有四种乘法的时候,各位大约就是这样的表情了吧?

实际上,NumPy数组乘法远不止四种。为了在写作和阅读时保持清晰的逻辑和清醒的头脑,本文仅对四种最常见的数组乘法给出详细说明,并用一道数学题来演示向量点乘和叉乘的用法。

1. 星乘(*)

先声明一下:星乘这个说法,是我自己创造的,因为我实在不知道数组的这种乘法有没有其他高大上的名字,只好用运算符来表示了。所谓数组星乘,就是数组的对应元素相乘,这也是初学NumPy的同学最早接触到的数组乘法。

>>> import numpy as np
>>> a = np.array([1,2,3])
>>> b = np.array([4,5,6])
>>> a*b
array([ 4, 10, 18])

对于多维数组,星乘的规则也是一样。

>>> a = np.arange(6).reshape((2,3))
>>> b = np.arange(6,12).reshape((2,3))
>>> a
array([[0, 1, 2],
    [3, 4, 5]])
>>> b
array([[ 6, 7, 8],
    [ 9, 10, 11]])
>>> a*b
array([[ 0, 7, 16],
    [27, 40, 55]])

即使两个数组的shape不一样,只要满足特定条件,同样可以用星号相乘,且满足交换律。

>>> a = np.arange(6).reshape((2,3))
>>> b = np.array([1,2,3])
>>> a
array([[0, 1, 2],
    [3, 4, 5]])
>>> b
array([1, 2, 3])
>>> a*b
array([[ 0, 2, 6],
    [ 3, 8, 15]])
>>> b*a
array([[ 0, 2, 6],
    [ 3, 8, 15]])

2. 点乘(np.dot)

在数学上,向量点乘就是两个向量的对应位相乘后求和,因此向量点乘得到的是标量。

向量点乘的几何意义是两个向量的模之积再乘以二者夹角的余弦值。这意味着,如果两个向量互相垂直,则其点积为零。反过来说,两个不为零的向量的点积等于零,则两个向量垂直。

numpy.dot()函数提供了点乘运算。对于一维数组,NumPy的点乘就是向量点乘,其结果是一个标量。对于多维数组,则需要满足一定条件才能实现点乘,且其结果不再是标量,而是一个多维数组。比如,NumPy的矩阵相乘,就是二维数组的点乘,参与点乘的第一个数组的列数必须等于第二个数组的行数。

>>> a = np.array([1,0,0])
>>> b = np.array([0,1,0])
>>> np.dot(a,b) # 向量a和向量b相互垂直,其点积为0
0
>>> a = np.arange(6).reshape((2,3))
>>> b = np.arange(6,18).reshape((3,4))
>>> np.dot(a,b) # 满足点乘条件
array([[ 38, 41, 44, 47],
    [128, 140, 152, 164]])
>>> np.dot(b,a) # 不满足点乘条件
Traceback (most recent call last):
 File "<pyshell#38>", line 1, in <module>
  np.dot(b,a)
 File "<__array_function__ internals>", line 6, in dot
ValueError: shapes (3,4) and (2,3) not aligned: 4 (dim 1) != 2 (dim 0)

3. 叉乘(np.cross)

在百度和知乎上,有很多人说叉积就是外积,也有人提出不同意见。我在这里仅使用叉乘或叉积等确定无误的概念,以免误人子弟。在数学上,二维平面的向量叉乘,其结果是以两个向量为边的菱形的面积,三维空间的向量叉乘,其结果是仍然是一个向量,且垂直于相乘的两个向量,也就是参与相乘的两个向量决定的平面的法向量。nunpy.cross()函数可以实现向量(一维数组)叉乘,也可以实现二维或三维数组的叉乘。

>>> a = np.array([2,0])
>>> b = np.array([2,2])
>>> np.cross(a,b) # 平面向量叉乘,其结果是以两个向量为边的菱形的面积
array(4)
>>> a = np.array([1,0,0])
>>> b = np.array([0,1,0])
>>> np.cross(a,b) # x轴叉乘y轴,得到z轴
array([0, 0, 1])
>>> np.cross(b,a) # 叉乘交换顺序,得到反向的法向量
array([ 0, 0, -1])

4. 外乘(np.outer)

这里的外乘,类似于星乘,并不是通用的概念,也是我自己编造的一个说法,来源于numpy.outer()函数。从字面看,outer()函数更像是求外积,但从实际效果看,更像是笛卡尔直积,因此我这里用了“外乘”而不是“外积”。那么,outer()函数究竟能作什么呢?

>>> a = np.array([1,2,3])
>>> b = np.array([4,5,6,7])
>>> np.outer(a,b)
array([[ 4, 5, 6, 7],
    [ 8, 10, 12, 14],
    [12, 15, 18, 21]])

数组A外乘数组B,返回一个二维数组,这个二维数组的第i行是数组A的第i个元素星乘数组B。

5. 判断两条直线是否相交

假设abcd是欧氏空间中不重合的四个点,如何判断过点ab的直线和过点cd的直线是否相交?如果使用空间解析几何的方式来解决问题,对于一般程序员来说将是一个难题。不过,如果你熟悉NumPy,理解点积(np.dot)和叉积(np.cross)的话,解决这个问题就变得非常容易了。具体思路是这样的:

计算向量ab和向量cd的叉积,得到向量orth如果orth的每一个元素都是零,则表示直线ab平行于直线cd,二者不可能相交;否则,orth就同时垂直于向量ab和向量cd计算向量orth和向量ac的点积,得到标量dp如果dp为零,表示向量orth垂直于向量ac,此时直线ab和直线cd在同一个平面上,且一定相交于某点

以上思路写成代码如下。

>>> a = np.array([1,2,3])
>>> b = np.array([4,5,6,7])
>>> np.outer(a,b)
array([[ 4, 5, 6, 7],
    [ 8, 10, 12, 14],
    [12, 15, 18, 21]])

到此这篇关于细说NumPy数组的四种乘法的使用的文章就介绍到这了,更多相关NumPy数组乘法内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • 对numpy 数组和矩阵的乘法的进一步理解

    1.当为array的时候,默认d*f就是对应元素的乘积,multiply也是对应元素的乘积,dot(d,f)会转化为矩阵的乘积, dot点乘意味着相加,而multiply只是对应元素相乘,不相加 2.当为mat的时候,默认d*f就是矩阵的乘积,multiply转化为对应元素的乘积,dot(d,f)为矩阵的乘积 3. 混合时候的情况,一般不要混合 混合的时候默认按照矩阵乘法的, multiply转化为对应元素的乘积,dot(d,f)为矩阵的乘积 总结:数组乘法默认的是点乘,矩阵默认的是矩阵乘法,混

  • 细说NumPy数组的四种乘法的使用

    当孔乙己说回字有四样写法的时候,相信各位都是这样的表情吧? 但是,如果孔乙己说NumPy数组有四种乘法的时候,各位大约就是这样的表情了吧? 实际上,NumPy数组乘法远不止四种.为了在写作和阅读时保持清晰的逻辑和清醒的头脑,本文仅对四种最常见的数组乘法给出详细说明,并用一道数学题来演示向量点乘和叉乘的用法. 1. 星乘(*) 先声明一下:星乘这个说法,是我自己创造的,因为我实在不知道数组的这种乘法有没有其他高大上的名字,只好用运算符来表示了.所谓数组星乘,就是数组的对应元素相乘,这也是初学Num

  • 浅谈numpy数组的几种排序方式

    简单介绍 NumPy系统是Python的一种开源的数组计算扩展.这种工具可用来存储和处理大型矩阵,比Python自身的嵌套列表(nested list structure)结构要高效的多(该结构也可以用来表示矩阵(matrix)). 创建数组 创建1维数组: data = np.array([1,3,4,8]) 查看数组维度 data.shape 查看数组类型 data.dtype 通过索引获取或修改数组元素 data[1] 获取元素 data[1] = 'a' 修改元素 创建二维数组 data

  • JS中循环遍历数组的四种方式总结

    本文比较并总结遍历数组的四种方式: for 循环: for (let index=0; index < someArray.length; index++) { const elem = someArray[index]; // ··· } for-in 循环: for (const key in someArray) { console.log(key); } 数组方法 .forEach(): someArray.forEach((elem, index) => { console.log(

  • 详解Java数组的四种拷贝方式

    目录 深拷贝与浅拷贝的区别 1.for循环进行拷贝 拷贝数值类型 拷贝引用类型 2.copyof/copyOfRange 拷贝数值类型 拷贝引用类型 3.arraycopy 拷贝数值类型 拷贝引用类型 4.clone 拷贝数值类型 拷贝引用类型 5.总结 深拷贝与浅拷贝的区别 假设现在有原数组A以及拷贝后的数组B,若是改变A中的某一个值,B数组随之相应的发生变化的拷贝方式称为浅拷贝,反之B数组不受影响,则称为深拷贝:简单总结一下两者的概念: 深拷贝:拷贝后,修改原数组,不会影响到新数组: 浅拷贝

  • Python数据分析numpy数组的3种创建方式

    目录 一.使用列表创建numpy数组 1 使用numpy创建一维数组 2 使用numpy创建二维数组 3 使用numpy创建一维数组,源为不同数据类型的列表 二.通过读取图片创建多维numpy数组 1 将图片信息读取到numpy数组中 2 在jupyter中读取图片数据后并显示 3 对图片数组数据处理 三.通过指定函数生成numpy数组 1 生成多维数组 2 生成一维线性数组 3 生成一维等差数列 4 生成随机的多维数组 一.使用列表创建numpy数组 1 使用numpy创建一维数组 2 使用n

  • Numpy数组转置的两种实现方法

    Numpy数组转置很容易,两种写法 np_array = np.array([[1, 2], [3, 4]]) np_array.transpose() np.transpose(np_array) 但是一维数组转置的时候有个坑,光transpose没有用,需要指定shape参数 array_1d = np.array([1, 2]) print array_1d.shape, array_1d.transpose() array_1d.shape = (2, 1) print array_1d

  • numpy数组拼接简单示例

    NumPy数组是一个多维数组对象,称为ndarray.其由两部分组成: ·实际的数据 ·描述这些数据的元数据 大部分操作仅针对于元数据,而不改变底层实际的数据. 关于NumPy数组有几点必需了解的: ·NumPy数组的下标从0开始. ·同一个NumPy数组中所有元素的类型必须是相同的. NumPy数组属性 在详细介绍NumPy数组之前.先详细介绍下NumPy数组的基本属性.NumPy数组的维数称为秩(rank),一维数组的秩为1,二维数组的秩为2,以此类推.在NumPy中,每一个线性的数组称为是

  • Python遍历numpy数组的实例

    在用python进行图像处理时,有时需要遍历numpy数组,下面是遍历数组的方法: [rows, cols] = num.shape for i in range(rows - 1): for j in range(cols-1): print(num[j, i]) 以上这篇Python遍历numpy数组的实例就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持我们. 您可能感兴趣的文章: Python Numpy 数组的初始化和基本操作 python中numpy包使用教程之

  • 取numpy数组的某几行某几列方法

    这个操作在numpy数组上的操作感觉有点麻烦,但是也没办法. 例如 a = [[1,2,3], [4,5,6], [7,8,9]] 取 a 的 2 3 行, 1 2 列 c=[1,2] d =[0,1] 若写为 b = a[c,d] output: [4 8] 取的是 第二行第一列 和第三行第二列的数据 这并不是我们想要的结果. 正确做法是: b = a[c]先取想要的行数据 b = b[:,d] print(b) output: [[4 5] [7 8]] 这才是我们想要的结果.必须要经过这两

随机推荐