matlab转python_将你的科学计算从Matlab迁移到Python?

对Python不错的吐槽,刚好在用Python,转过来可以讨论下呵。

-----------------------------------

为什么要用问句作为文章的标题呢,因为我的答案是NO!Absolutely Don’t!

一切的一切起源于我看了一篇英文文章,说使用Python作科学计算有时比Matlab更加高效,还有那无数次见到的牛逼公式:

,看的我心潮澎湃,我就寻思了,反正最近在做的那个算法用Matlab跑实验跑得不是太理想,要不咱也迁移一把,由于今天比较蛋疼,就决定开始尝试了,经过蛋疼的一天,我得出了开头那个结论:如果你有现成的Matlab算法,还是Matlab吧,如果你像我一样蛋疼,那就迁移吧。不相信,那就听我把遇到的一堆乱七八糟的事情娓娓道来吧,其中夹杂着我的一些弱弱的解决方案~~

.mat数据集文件的导入

由于现有的数据集一般都是以Matlab的格式.mat的形式出现的,Matlab可以轻松的load语句搞定,但Python就不行了,花时间将mat文件提取成普通文本文件必然更心烦。其实这点Python肯定已经想到了,解决方案就是使用Scipy提供的函数,具体如下:

1

2

importscipy as sp

dataset=sp.io.matlab.mio.loadmat(dataset_name)

其中dataset_name就是我们需要导入的.mat文件,但问题又来了,导入后返回的dataset变量是一个“字典”的数据结构,它的key就是储存的变量名称,而对应的value就是变量的内容。这个操作并不像Matlab那样直接将.mat里的变量载入workspace,那我们当然还需要进一步使dataset中存储的变量暴露出来,对应的内容赋给对应的变量名称。可以查看dataset变量的组成,发现除了我们自己的变量,还有另外三个小东西:’__globals__’,’__header__’,’__version__’,它们标识了.mat文件的基本信息,但我们并不需要,所以还需要去掉它们。最终,我们通过一段代码实现:

1

2

3

4

exclude=['__globals__','__header__','__version__']

forobjindataset.keys():

ifobjnotinexclude:

exec(obj+' = dataset[" '+obj+' "] ')

通过exec我们就实现了类似语句data = dataset["data"]的功能。OK,到这里,第一个任务完成,撒花~~可以看到,用Matlab一句load搞定的问题,这里搞了大半天。

迁移everything

由于我搞的是代码迁移,即将原来Matlab的代码改成Python代码,本来还觉得迁移就是稍微改改,最后发现要迁移不是一点,而是 almost everything。首先一个最严重的问题:( ) 和 [ ] 的问题,这恐怕是迁移过程中最频繁的一个改动,这是为什么呢?很简单,因为Matlab中取矩阵元素(即Python中所说的‘slice’切片操作)用的是小括号,而Python中用的是中括号,还有比这更fuck的事情吗,因为函数调用也是小括号,所以放弃查找替换这不切实际的念头吧,这个恐怕只能手动。别以为这样就完事了,更琐碎的东西等着你,下面的表格可以帮助你理解什么是我说的everything。

操作

Matlab

Python

注释

%

#

开始索引

1

0

矩阵连接

[a, b]

numpy.concatenate(a, b)

循环和分支语句

未结束的条件行以,结尾

结束需要end

未结束的条件行以:结尾

结束不需要任何东西

产生全0全1矩阵

zeros(m, n) 和 ones(m, n)

numpy.zeros((m, n)) 和 numpy.ones((m, n))

整除问题

/ 直接取准确结果,不存在整除问题

/ 两遍都是整数时为整除

分子或分母需要加float强制转换

乘方

a^b

a**b

矩阵向量转置

单引号 ‘ 搞定

没有重载 ‘ 操作符,需要调用 .transpose 或 .T

结构体数组

直接{ }搞定

{ }指的是字典数据结构,没有结构体的概念,只能使用“对象列表”搞定

向量矩阵相乘

a*b 代表正常的矩阵相乘,也就是说a的列数必须和b的行数匹配的那种

a.*b 代表对应元素相乘,即elementwise,a和b的维数必须相等

a*b 代表对应元素相乘,即elementwise,a和b的维数必须相等

dot(a, b) 代表正常的矩阵相乘,也就是说a的列数必须和b的行数匹配的那种

OK,这么些个问题需要解决,有些还是可以接受的,毕竟两个不同的语言嘛,操作符什么的不一样还行,有的就比较恶心了。其中最让人难以理解的就是numpy的zeros和ones不明白为啥参数一定要是一个“元组”,不知道当初创造这个时怎么想的,搞的加了两层括号。而最变态的就是矩阵向量的相乘了,Matlab分的很清,单独的 * 号就是矩阵相乘,而 .* 就是对应元素相乘,而Python中单独的 * 号表示元素相乘,作用与Matlab恰恰相反,真正的矩阵乘法居然需要调用dot函数才能完成,而dot只接受两个参数,可想而知,一堆矩阵相乘的时候得多壮观啊,譬如:

,类似的变态事还有矩阵连接,本来Matlab两矩阵放一起就能连接,Numpy非要用一个函数,你用函数我忍了,你还用那么长一个函数concatenate,要是连接几个矩阵咋办,一行能写下吗?大哥,我彻底凌乱了~

后话

鉴于上述的种种让人闹心的原因,我的移植工作没有坚持下去。当然,我写下这篇文章,并没有诋毁Python在做科学计算这方面的潜力,更没有贬低Python的意思,不得不承认接触Python越多,越觉得它牛逼,我仅仅表达的是要从Matlab迁移到Python有点得不偿失,或许一开始就直接从Python开始是个不错的选择,不存在迁移,直接从头开始。但如果你想我一样,有现成的Matlab代码了,那咱就老实Matlab吧~~

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值