MATLAB讲Python
MATLAB是一个伟大的计算环境的工程师和科学家。MATLAB还提供了对通用语言的访问,包括C/ c++、Java、Fortran、。net和Python。今天的嘉宾博客竹内俊二,想谈谈MATLAB与Python的结合使用.
目录
为什么不两者都用呢?
当我们讨论语言时,我们经常会遇到错误的选择你觉得你必须选择其中之一。实际上,两者都可以使用。我们大多数人都不是独自工作的。作为更大团队的一部分,您的工作通常是包含多种语言的更大工作流的一部分。这就是为什么MATLAB提供了与其他语言(包括Python)的互操作性。您的同事可能想利用您的MATLAB代码,或者您需要从IT系统访问基于python的功能。MATLAB支万博1manbetx持您的工作流程在两个方向。
今天我想重点谈谈从MATLAB调用Python在基于MATLAB的工作流中利用一些现有的Python功能。
在这篇文章中,我们将看到:
- 如何将Python中的数据导入MATLAB
- 如何将数据从MATLAB传递到Python
- 如何在MATLAB中使用Python包
在MATLAB中建立Python
MATLAB支万博1manbetx持Python 2.7、3.6和3.7在撰写本文时(R2019b)。这里是另一个有用的链接.
我假设您已经知道如何安装和管理您选择的平台上的Python环境和依赖项,在这里我将不讨论它,因为它本身就是一个复杂的主题。
让我们在MATLAB中启用对Python的访问。您需要找到Python可执行文件的完整路径。下面是一个Windows示例。在Mac和Linux上,您的操作系统命令可能不同。
pe=pyenv;如果体育状况==“NotLoaded”[~,exepath]=系统(“python在哪里”);pe=pyenv(“版本”,exepath);终止
如果这不起作用,还可以将路径作为字符串传递给Python可执行文件。
pe=pyenv(“版本”,'C:\Users\username\AppData\Local\your\python\path\python.exe')
myPythonVersion =体育。版本py.print (“你好,Python!”)
myPythonVersion=“3.7”你好,Python!
空手道俱乐部
韦恩·扎卡里发表数据集该网站包含了20世纪70年代美国一所大学空手道俱乐部的34名成员之间的友谊社交网络。这个俱乐部里爆发的一场争执最终使它分裂成两个派别。我们想看看,我们是否能根据俱乐部的人际关系,用算法来预测俱乐部将如何解体。
此数据集包含在NetworkX,一个用于Python的复杂网络包。我们可以很容易地开始使用这个包导入数据集。
我正在使用Networkx2.2。要在Python中检查包的版本,通常会使用version-package属性,如下所示:
>>>networkx.\uuuu版本__
MATLAB不支持万博1manbetx类名称或以下划线(\)字符开头的其他标识符。请使用以下命令获取软件包上的帮助内容,包括其当前版本。
>救命啊(“networkx”)
导入还是不导入
通常,在Python脚本开始时执行此操作。
进口networkx像nxG=nx.空手道俱乐部图()
但是,在MATLAB中不建议这样做,因为进口MATLAB中的函数与Python中的函数不同。
MATLAB调用Python的方法是使用派克,后面跟着一个包或方法,如下所示:
nxG=py.networkx.karate_club_graph();
如果必须使用进口,您可以按如下方式执行:
进口py.networkx*nxG=空手道俱乐部图();
如您所见,当省略时,很难记住我们正在调用Python方法派克,当您开始在同一个脚本中混合使用MATLAB代码和Python代码时,这可能会令人困惑。
从Python对象提取数据
以下代码返回NetworkX图形对象中的空手道俱乐部数据集。
myDataType=class(nxG)
myDataType='py.networkx.classes.graph.graph'
您可以看到此对象上可用的方法,如下所示:
方法(nxG)
您还可以查看此对象的属性。
属性(nxG)
NetworkX图形包含边缘属性,该属性返回被调用的对象艾奇维.
edgeL=nxG.edges;myDataType=class(edgeL)
myDataType='py.networkx.classes.reportviews.EdgeView'
要在MATLAB中使用此Python对象,第一步是将该对象转换为核心Python数据类型,如Python列表.
edgeL=py.list(edgeL);myDataType=class(edgeL)
myDataType='py.list'
现在edgeL包含一个Python列表存储为Python的节点对元组元素。每个节点对表示图中的一条边。让我们看看前5条元组值。
listContent=edgeL(1:5)
listContent =没有属性的Python列表。[(0,1), (0,2), (0,3), (0,4), (0,5)]
处理Python列表和元组
Python处理列表或元组通常是这样的,在循环中处理单个元素。
对于我在l:打印我#L是这个列表对于u、 五在里面t:打印((u,v))#T是这个元组
MATLAB的方法是使用数组。巨蟒列表可以转换成单间牢房大堆
edgeC=单元格(edgeL);myDataType=类(edgeC)
myDataType =“细胞”
这单间牢房数组包含Python元组元素。
myDataType =类(edgeC {1})
myDataType='py.tuple'
巨蟒元组也可以转换为单间牢房数组。转换内部元组元素,我们可以使用cellfun.
= cellfun(@cell, edgeC,“UniformOutput”,false);myDataType=class(edgeC{1})
myDataType =“细胞”
结果是嵌套的单间牢房数组包含Pythonint值。
myDataType=class(edgeC{1}{1})
myDataType='py.int'
处理Python字典
现在让我们也从数据集中提取节点。我们可以按照边的步骤来做。
nodeL=py.list(nxG.nodes.data);nodeC=cell(nodeL);nodeC=cellfun(@cell,nodeC,“UniformOutput”、假);
一个内单间牢房数组包含两个Pythonint和dict元素。
cellContent=nodeC{1}
cellContent = 1×2 cell array {1×1 py.int} {1×1 py.dict}
Pythondict是基于键值对的数据类型。在这种情况下,关键是“俱乐部”价值是“你好先生”.
cellContent=nodeC{1}{2}
cellContent=Python dict,不带属性。{'club':'Mr.Hi'}
嗨先生是俱乐部的空手道教练。Python中的另一个值dict是“警官”,该官员是俱乐部的领导人。他们是各自派系的关键人物。节点属性表示单个节点属于哪个派系。在本例中,节点1属于Hi先生的派系。
Python处理dict通常是这样的,在循环中处理单个元素。
对于k、 五在里面d、 项目():打印(k、v)
同样,MATLAB的方法是使用数组dict可以转换为结构大堆
nodeAttrs=cellfun(@(x)struct(x{2}),nodeC);myDataType=class(nodeAttrs)
myDataType =“结构”
我们可以将单个值提取到一串这个俱乐部显然在各派之间平分。
nodeAttrs=arrayfun(@(x)字符串(x.club),nodeAttrs;制表(nodeAttrs)
价值计数百分比Hi先生17 50.00%官员17 50.00%
我们把Hi先生阵营的节点取出来。
group_hi = 1:长度(nodeAttrs);group_hi = group_hi(nodeAttrs == . .“你好先生”);
MATLAB中图形的可视化
MATLAB还提供图形和网络功能我们可以用它们来可视化图形。
让我们转换Pythonint要删除的边列表中的值双并将边中的节点提取为单独的向量。
s=cellfun(@(x)double(x{1}),edgeC);t=cellfun(@(x)double(x{2}),edgeC);
MATLAB图表需要节点的列向量。让我们转置它们。
s=s’;t=t’;
Python中的节点索引以0开头,但MATLAB中的节点索引必须以非零值开头。
S = S + 1;T = T + 1;
现在,我们准备创建一个MATLAB图形对象并绘制它,突出显示Hi先生的派系。
图G = (s, t);G.Nodes.club = nodeAttrs ';图P1 = plot(G);突出(P1, group_hi,“NodeColor”,"D95319",“EdgeColor”,"D95319")头衔({“扎卡里空手道俱乐部”,“橙色代表Hi先生的派系”})
将数据从MATLAB传递到Python
在本例中,我们已经有了NetworkX图形对象,但是为了完整性,让我们看看如何在MATLAB中创建这个Python对象。
让我们创建一个空的NetworkX图。
nxG2 = py.networkx.Graph ();
您可以使用添加\u边\u自方法。它接受Python列表属于元组像这样的元素:
[(1,2),(2,3),(3,4)]
这在MATLAB中不是一个有效的语法。我们可以用1xN单间牢房像这样的节点对数组:
myListofTuples={{1,2},{2,3},{3,4};
当我们通过这个单间牢房数组来py.list, MATLAB自动将其转换为Python列表属于元组元素。
myListofTuples=py.list(myListofTuples);myDataType=class(myListofTuples{1})
myDataType='py.tuple'
让我们从MATLAB中提取边列表图表.这是一个78x2的矩阵双在MATLAB中,双是默认的数字数据类型。
edgeL=G.Edges.EndNodes;myDataType=class(edgeL)
myDataType='double'
如果我们将双Python的值列表,这些值将被转换为Python浮动,但Python中的默认数字数据类型为int.所以我们不能使用双.
listContent=py.list(edgeL(1,:))
listContent=不带属性的Python列表。[1.0, 2.0]
此外,Python的索引是基于0的,而MATLAB是基于1的。我们需要转换数组双要素int8并将变量元素更改为基于0的索引。
edgeL = int8(edgeL) - 1;myDataType =类(edgeL)
myDataType = ' int8 '
我们可以使用num2cell转换矩阵int8将值转换为78x2单间牢房数组,其中每个元素位于单独的单元格中。
edgeL=num2单元格(edgeL);myDataType=class(edgeL)
myDataType =“细胞”
通过转换78x2,我们可以将节点对放置在同一个单元中单间牢房阵列到78x1单间牢房数组的使用num2cell.
edgeL=num2单元(edgeL,2);[行,列]=大小(edgeL)
行=78列=1
这个添加\u边\u自方法需要一个1xN Python列表.现在,让我们将其转换为1xN单间牢房通过转置Nx1单间牢房数组,将其转换为Python列表并将其添加到空的NetworkX图形对象中。
nxG2.从(py.list(edgeL'))添加边;
这些边已添加到NetworkX图形对象。让我们检查前5个元组值。
edgeL=py.list(nxG2.edges);listContent=edgeL(1:5)
listContent =没有属性的Python列表。[(0,1), (0,2), (0,3), (0,4), (0,5)]
这些节点也被添加到图中,但它们当前没有任何属性,正如您在下面节点列表的前3个元素中看到的那样。
nodeL=py.list(nxG2.nodes.data);listContent=nodeL(1:3)
listContent=不带属性的Python列表。[(0,{},(1,{},(2,{})]
要添加属性,我们需要使用设置节点属性此方法需要一个嵌套的Pythondict.以下是如何创建dict在MATLAB中。
myDict=py.dict(pyargs(“钥匙”,“价值”))
myDict=没有属性的Python dict。{'key':'value'}
这个设置节点属性方法需要一个嵌套的dict.外面的钥匙dict节点和值是dict阵列这样的键值对的数目:
{0: {“俱乐部”:“你好先生”1}: {“俱乐部”:“警官”}}
不幸的是,这行不通,因为pyargs希望只有一个一串或字符以价值为关键。
>>py.dict(pyargs)(0,py.dict(pyargs(“俱乐部”,“你好先生”))))错误使用pyargs领域名字必须是一串标量或性格向量。
相反,我们可以创建一个空的dict,并添加内部dict从元组数据,使用基于0的索引使现代化方法是这样的:
attrsD=py.dict;对于ii=1:length(nodeAttrs)attrD=py.dict(pyargs(“俱乐部”(二),;attrsD.update(py.tuple({int8(ii-1),attrD}))终止
然后我们可以使用设置节点属性将属性添加到节点。
py.networkx.set_node_attributes (nxG2 attrsD);nodeL=py.list(nxG2.nodes.data);listContent=nodeL(1:3)
listContent=不带属性的Python列表。[(0,{'club':'Mr.Hi'}),(1,{'club':'Mr.Hi'}),(2,{'club':'Mr.Hi'}]
NetworkX社区检测
NetworkX提供greedy_modularity_communities方法在图中查找社区。让我们试试这个算法,看看它能多好地检测派系!
由于该俱乐部分为两组,我们预计将看到两个社区。
communitiesL = py.networkx.algorithms.community.greedy_modularity_communities (nxG2);myDataType =类(communitiesL)
myDataType='py.list'
返回的Python列表包含3个元素。这意味着算法在该图中检测到3个社区。
num_communitieis=长度(communitiesL)
num_communitieis = 3
这个列表包含冻结.一条巨蟒冻结和Python一样吗设置,除了它的元素是不可变的之外设置类似于Python列表,但其所有元素都是唯一的,而列表可以多次包含同一元素。
listContent = communitiesL {1}
listContent=Python冻结集,不带属性。frozenset({32,33,8,14,15,18,20,22,23,24,25,26,27,28,29,30,31})
让我们把它转换成嵌套的细胞.
社区C=单元(社区L);社区C=单元F(@(x)单元(py.list(x)),社区C,“UniformOutput”,false);myDataType=class(社区C{1}{1})
myDataType='py.int'
内心最单间牢房包含Pythonint值。我们把它们转换成双.
对于ii = 1:length(communtiesc) communtiesc {ii} = cellfun(@double, communtiesc {ii});终止myDataType=class(社区C{1}(1))
myDataType='double'
因为在Python中节点是基于0的索引,所以我们需要在MATLAB中将它们改为基于1的索引。
社区c=cellfun(@(x)x+1,社区c,“UniformOutput”、假);
让我们在图中绘制社区。
P1 = plot(G);突出(P1, group_hi,“NodeColor”,"D95319",“EdgeColor”,"D95319")头衔({“扎卡里空手道俱乐部”,“橙色代表Hi先生的派系”})nexttile P2=绘图(G);突出显示(P2,社区C{1},“NodeColor”,“# 0072 bd”,“EdgeColor”,“# 0072 bd”)突出显示(P2,社区C{2},“NodeColor”,"D95319",“EdgeColor”,"D95319")突出显示(P2,社区C{3},“NodeColor”,“# 77 ac30”,“EdgeColor”,“# 77 ac30”)头衔({“扎卡里空手道俱乐部”,“基于模块化的社区”})
如果你比较这些情节,你可以看到右边橙色和绿色的两个社区,当它们结合在一起时,大致与Hi先生的派系重叠。
我们还可以看到:
- 社区1代表“军官”派系
- 社区3代表忠诚的“Hi先生”派系
- 社区2代表与两派都有联系的人
有趣的是,社区2最终站在了Hi的阵营一边。
让我们看看算法的输出和实际的派系之间是否有任何差异。
diff_elements=setdiff(组_hi,[communitiesC{2}communitiesC{3}]);diff_elements=[diff_elements setdiff([Communities C{2}Communities C{3}],group_hi)]
差异元素=9 10
社区检测算法非常接近于识别实际派系。
简化代码
到目前为止,我们一直在检查每个步骤中返回的数据类型。如果您已经知道数据类型,您可以将这些步骤组合成几行代码。
要获得空手道俱乐部的数据并创建一个MATLAB图,你可以这样做:
nxG=py.networkx.karate_club_graph();edgeC=cellfun(@cell,cell(py.list(nxG.edges)),“UniformOutput”,false);nodeC=cellfun(@cell,cell(py.list(nxG.nodes.data)),“UniformOutput”,false);nodeAttrs=cellfun(@(x)struct(x{2}),nodeC);nodeAttrs=arrayfun(@(x)string(x.club),nodeAttrs);s=cellfun(@(x)double(x{1}),edgeC)+1;t=cellfun(@(x)double(x{2}),edgeC)+1;G=graph(s,t);G.Nodes.club=nodeAttrs';
要从MATLAB数据创建一个Python图形,你可以这样做:
nxG2 = py.networkx.Graph ();= num2cell(int8(g.r egs . endnodes) - 1);nxG2.add_edges_from (py。列表(num2cell(edgeL, 2)')); attrsD = py.dict;对于ii = 1:length(G.Nodes.club) attrD = py.dict(pyargs(“俱乐部”(二),;attrsD.update(py.tuple({int8(ii-1),attrD}))终止py.networkx.set_node_attributes (nxG2 attrsD);
为了检测社区,你可以这样做:
社区C=cell(py.networkx.algorithms.community.贪婪的模块化社区(nxG2));社区C=cellfun(@(x)单元格(py.list(x)),社区C,“UniformOutput”、假);对于ii = 1:length(communtiesc) communtiesc {ii} = cellfun(@double, communtiesc {ii});终止社区c=cellfun(@(x)x+1,社区c,“UniformOutput”、假);
总结
在本例中,我们了解了如何在MATLAB中使用Python。一旦您了解了数据类型转换的工作原理,这就相当简单了。要记住的事项:
- Python是基于0的索引,而MATLAB是基于1的索引
- Python的默认数字数据类型是int而它是双对于MATLAB
- 将Python数据转换为适当类型的MATLAB数组,而不是循环
- 使用单间牢房Python的数组列表和元组
- 使用结构Python的数组dict
在本例中,我们在MATLAB工作流中使用Python库来获取数据和检测社区。我本可以在MATLAB中编写所有代码,但利用现有Python代码更容易,并且我能够在熟悉的MATLAB环境中完成任务,在那里我可以最高效地完成任务。
你是一个多才多艺的程序员吗?分享你是如何使用MATLAB和Python的在这里.
评论
如需留言,请点击在这里登录到您的MathWorks帐户或创建新帐户。