python矩阵乘法代码_python3 单行代码实现矩阵相乘

Python中有许多模块用来进行科学与数学的运算。

例如,numpy就是其中的一个,而且numpy中就有大量、好使的矩阵乘法的函数。

即便如此,我们还是可以探究一下如何用Python的自带函数,在一行内实现矩阵的乘法运算

以此,来体现Python代码的强大和简洁性。下面,就让我们开始吧~

首先,让我们看一下数学上的矩阵是如何相乘的:

矩阵相乘数学原理:设A为m×p的矩阵,B为p×n的矩阵,那么称m×n的矩阵C为矩阵A和矩阵B的乘积,记作 C=AB,其中矩阵C中的第 i 行第 j 列的元素可以表示为:

如下图所示:引用自百度百科

所以,矩阵相乘其实是对应的行和列对应位置相乘再相加,将合数放到相应的位置。

详细点说,C矩阵的第3行第4列位置上的数,其实是A矩阵(前一个矩阵)的第i行,和B矩阵(后一个矩阵)的第j列,一次对应相乘后在将他们相加。

矩阵相乘代码实现:

下面,我们来看一下Python中是如何用一行代码来实现矩阵相乘的:

[[sum(map(lambda a: a[0]*a[1], zip(l, s))) for l in zip(*MA)] for s in MB]

这一行代码就可以将MA矩阵和MB矩阵相乘,得到一个相乘后的矩阵了~

可以看到,其中有很多的内建函数,例如:zip()、map()、sum()、lambda。

当然,还有我们的核心语法——列表生成式。

这些内建函数,我们来一个一个的详细讲解清楚:

lambda函数 (又称:匿名函数)

这个函数是用来定义一个简单的、只包含传参和返回的函数,什么意思呢?

lambda函数本身是是这样的:

Function = lambda x, y:x*y

我们也可以将它视为这样的形式:

def Function(x, y):

return x*y

所以说,lambda函数返回的是一个类似于函数调用借口的东西,将函数的调用变得简单化。

在我们的一行代码中,它执行的主要是对应相乘相加中的相乘工作。

为什么一定要用lambda函数呢?

这是因为,如果我们想快速的将 A矩阵的第i行和B矩阵的第j列 进行大批量的对应乘法的时候,map()函数是我们的最佳选择,否则就要再写两个列表生成式。(map()函数和列表生成式在后面会逐个讲到,这里只是稍作引用)而map()函数要接收的 操作(或者说函数),必须是一个正式的函数,而不能是一个类似于“a*b”的表达式。

这就是我们为什么必须要使用lambda函数的原因。

sum()函数(又称:求和函数)

sum()函数十分简单。

顾名思义,且粗略的来说,sum()函数是用来将一个列表中的所有元素进行求和操作的内建函数。

这里,我使用它来进行对应相乘后的相加操作。

因为在map()函数操作过后,生成的是一个map对象,这时我们可以灵活地使用sum()函数,来对所有可以求和的东西进行求和。这也是python内建函数的强大之处。

map()函数(又称:映射函数)

恭喜你,恭喜你已经坚持到了现在!现在我们的旅途只剩下最后一座高山,翻过去就是一路坦途了!

map()函数,就是将一个“函数”映射到一个数组上(其实是可迭代对象),在我们的程序中,我们将zip()处理过的,已经把对应位置打包成一起了的,每个位置是两个数字的,一串数组。将这串数组的每个元素内部的两个数进行乘法,然后输出出去。这时,这串数组的每个元素,都变成了先前两个数的乘积!我们通过map就实现了对应位置相乘的功能,这真是太好了!

zip()函数(又称:打包函数)

现在到了zip函数了!这个可以很直观的理解,什么意思呢?

我想请你看下这个矩阵转置的程序:

tranM = zip(*M)

我解释一下其中的小难点,在一个数组前面加一个“*"代表将这个数组拆分,将他的每个元素都拆出来。而zip()函数所做的就是将几个数组,他们所有数组的第一个位置组成一个新数组,第二个组成第二个数组,第三个组成第三个。。。。以此类推。看出什么了吗?这相当于将原数组的第一列化成了新数组的第一行,将原数组的行转换成了新数组的列,这就是转置了。

而在我们的程序中,zip函数帮助我们将本来对矩阵的按行获取,经过转置变成按列获取,这使得矩阵乘法的对应行和对应列相乘相加变为可能。

按照zip()的运算规则,你能不能猜出在map中,为什么还要使用一次zip函数吗?

很简单,因为map函数是将一个数组的元素进行相乘,数组中只能有两个数字,而我们给过去的并不是这样的。我们需要将它们对应位置的数字进行合并,将它们按位置分开,才能进行map()操作。这就是zip()函数在程序中的作用。

下面,就是Python中十分强大,也十分有用的强大语法之一——列表生成式

列表生成式:

列表生成式的意思也很好解释,这里先给出几个例子:

>>>l = [i for i in range(4)]

>>>print(l)

[0, 1, 2, 3]

>>>l = [[0 for i in range(2)] for j in range(2)]

>>>print(l)

[[0, 0], [0, 0]]

看懂了吗?列表生成式就是按照后边的规则,一次生成前面的元素。而元素可以是一个结合了i和j的表达式,也能使很多很多复杂的函数,他都会一次生成,并且组成列表。

对于这种强大的语法糖,我只能说,真甜!

以上就是一行代码进行矩阵相乘的解析与源码了,希望大家喜欢。如果这篇文章能够帮到你,或者让你学到了东西,又或者你就是想给我点赞同和感谢,那就请尽情的点吧~哈哈哈

谢谢大家

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值