MATLAB Python说话
MATLAB是一个伟大的计算环境的工程师和科学家。MATLAB还提供对通用语言的访问,包括C/ c++, Java, Fortran, . net和Python。今天的嘉宾博客古原竹内,想谈谈使用MATLAB与Python.
内容
为什么不使用两者?
当我们讨论语言时,我们经常遇到一个假选择你觉得你必须选择一个或另一个。实际上,您通常可以使用两者。我们大多数人都不独自工作。作为更大团队的一部分,您的工作往往是涉及多种语言的更大工作流程的一部分。这就是为什么Matlab提供与其他语言的互操作性,包括Python。您的同事可能希望利用您的MATLAB代码,或者您需要从IT系统访问基于Python的功能。Matlab在金宝app两个方向上都支持您的工作流程。
今天我想重点讲从matlab调用python在基于matlab的工作流中利用一些现有的Python功能。
在这篇文章中,我们将看到:
- 如何从Python导入数据到MATLAB
- 如何从MATLAB传递数据到Python
- 如何使用一个Python包在MATLAB
在MATLAB中设置Python
Matlab支金宝app持Python 2.7, 3.6和3.7截至撰写本文(R2019b)。这是另一个有用的例子链接.
我假设您已经知道如何在您的选择平台上安装和管理Python环境和依赖关系,我不会在这里讨论它,因为它是自己的复杂主题。
让我们在MATLAB中访问Python。您需要找到Python可执行文件的完整路径。下面是Windows的一个例子。在Mac和Linux上,您的操作系统命令可能不同。
pe = pyenv;如果体育。状态= =“未加载”[~, exepath] =系统(“巨蟒”);pe = pyenv (“版本”, exepath);结束
如果这不起作用,你也可以把路径作为字符串传递给你的Python可执行文件。
pe = pyenv (“版本”,“C: \ \用户名\ AppData \用户当地\ \ python \路径\ python.exe)
myPythonVersion =体育。版本py.print (“你好,Python !”)
myPythonVersion = "3.7"你好,Python!
空手道俱乐部的数据集
韦恩·扎卡里发表了一数据集该网站是上世纪70年代美国一所大学空手道俱乐部34名成员之间的社交网络。这个俱乐部爆发了一场争执,最终使它分裂成两个派别。我们想看看能否根据人际关系从算法上预测俱乐部将如何解散。
包含此数据集NetworkX,一个复杂的Python网络包。我们可以很容易地开始使用这个包导入数据集。
我使用的是NetworkX 2.2。要在Python中检查包的版本,你通常会像这样使用version package属性:
> > > networkx.__version__
MATLAB不支持金宝app类名或以下划线(_)字符开头的其他标识符.相反,使用下面的内容来获取包上的帮助内容,包括它的当前版本。
> py.help ('networkx')
导入或不导入
通常,您在Python脚本的开始部分执行此操作。
进口networkx作为nxG = nx.karate_club_graph ()
然而,这是不推荐在MATLAB,因为行为的进口函数在MATLAB是不同于Python的。
MATLAB调用Python的方法是使用py,后面跟着一个包或方法,像这样:
nxG = py.networkx.karate_club_graph ();
如果你必须使用进口,你可以这样做:
进口py.networkx。*nxG = karate_club_graph ();
正如您所见,很难记住,我们在省略时呼叫Python方法py,当您开始在同一个脚本中混合MATLAB代码和Python代码时,可能会感到困惑。
从Python对象中提取数据
以下返回NetworkX图形对象中的空手道俱乐部数据集。
myDataType =类(nxG)
myDataType = ' py.networkx.classes.graph.Graph '
你可以看到这个对象上可用的方法如下:
方法(NXG)
您还可以看到这个对象的属性。
属性(NXG)
NetworkX图包含边缘返回一个对象的属性EdgeView.
edgeL = nxG.edges;myDataType =类(edgeL)
myDataType = ' py.networkx.classes.reportviews.EdgeView '
要在MATLAB中使用这个Python对象,第一步是将对象转换为一个核心Python数据类型,比如Python列表.
edgeL = py.list (edgeL);myDataType =类(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是的列表为u, v在师:打印((u, v))#t是的元组
MATLAB的方法是使用数组。Python列表可以转换成细胞数组中。
edgeC =细胞(edgeL);myDataType =类(edgeC)
mydatatype ='cell'
这细胞数组包含Python元组元素。
myDataType =类(edgeC {1})
myDataType = ' py.tuple '
Python元组还可以转换成细胞数组中。改变内心世界元组元素,我们可以使用Cellfun..
edgec = cellfun(@cell,edgec,“UniformOutput”、假);myDataType =类(edgeC {1})
mydatatype ='cell'
由此产生的嵌套细胞数组包含Pythonint值。
myDataType =类(edgeC {1} {1})
myDataType = ' py.int '
处理Python字典
现在让我们还从数据集中提取节点。我们可以遵循与边缘的相同步骤。
nodeL = py.list (nxG.nodes.data);nodeC =细胞(nodeL);@cell, nodeC,“UniformOutput”、假);
境内细胞数组包含Python和int和d元素。
cellContent = nodeC {1}
cellContent = 1×2 cell array {1×1 py.int} {1×1 py.dict}
Pythond是基于键值对的数据类型。在这种情况下,关键是“俱乐部”它的值是“你好,先生”.
cellContent = nodeC {1} {2}
没有属性的Python字典。{“俱乐部”:“你好先生”}
嗨先生是俱乐部的空手道讲师。Python中的其他值d是“官”这个军官是俱乐部的领导。他们是各自派系的关键人物。节点属性指示单个节点属于哪个派系。在这个例子中,节点1属于Hi先生的派系。
Python处理d通常如此如此,在循环中处理单个元素。
为k、v在d.Items():打印(k,v)
同样,MATLAB的方法是使用数组。Pythond可以转换成结构体数组中。
nodeAttrs = cellfun(@(x) struct(x{2}), nodeC);myDataType =类(nodeAttrs)
myDataType =“结构”
我们可以将单个值提取到字符串数组中。俱乐部里显然各派平分秋色。
nodeAttrs = arrayfun(@(x) string(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);
马铃薯图期望节点的列向量。让我们转置。
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();
可以用。向图添加边add_edges_from方法。它接受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 =类(myListofTuples {1})
myDataType = ' py.tuple '
让我们从MATLAB中提取边表图.它是一个78x2的矩阵双倍的值。在MATLAB中,双倍的是默认的数字数据类型。
edgeL = G.Edges.EndNodes;myDataType =类(edgeL)
myDataType =“双”
如果我们转换数组双倍的值到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 = num2cell (edgeL);myDataType =类(edgeL)
mydatatype ='cell'
通过转换78x2,我们可以将节点对放置在同一个单元格中细胞数组到78x1细胞数组的使用num2cell.
edgeL = num2cell (edgeL 2);(行,关口)=大小(edgeL)
cols = 1
的add_edges_from方法需要一个1xN的Python列表.现在我们把它变成1xN细胞通过调换Nx1数组细胞数组,并将其转换为Python列表并将其添加到空网络x图对象中。
nxG2.add_edges_from (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, {})]
要添加属性,我们需要使用set_node_attributes方法。这个方法需要一个嵌套的Pythond.下面是如何创建d在MATLAB。
myDict = py.dict (pyargs (“关键”,“价值”))
myDict =没有属性的Python字典。{“关键”:“价值”}
的set_node_attributes方法期望一个嵌套的d.外面的钥匙d是节点,值是d数组键值对的定义如下:
{0: {“俱乐部”:“你好,先生”},1:{“俱乐部”:“官”}}
不幸的是,这行不通,因为Pyargs.只期待A.字符串或char值作为键。
> > py。d(pyargs(0, py.dict(pyargs(“俱乐部”,“你好,先生”))))错误使用Pyargs.场的名字必须是字符串标量或字符向量。
相反,我们可以创建一个空的d,加上内在d来自元组数据,使用基于0的索引,其中包含更新这样的方法:
attrsD = py.dict;为ii = 1:length(nodeAttrs) attrD = py.dict(pyargs()“俱乐部”G.Nodes.club (ii)));attrsD.update (py。元组({{int8(ii - 1), attrD}}))结束
然后我们可以用set_node_attributes向节点添加属性。
py.networkx.set_node_attributes (nxG2 attrsD);nodeL = py.list (nxG2.nodes.data);listContent = nodeL (1:3)
listContent =没有属性的Python列表。((0,{“俱乐部”:“你好先生”}),(1,{“俱乐部”:“你好先生”}),(2){“俱乐部”:“你好先生”}))
使用NetworkX进行社区检测
NetworkX提供了greedy_modularity_communities方法查找图中的社区。让我们尝试一下这个算法,看看它能在多大程度上检测出派系!
由于这个俱乐部分成了两个群体,我们希望看到两个社区。
communitiesL = py.networkx.algorithms.community.greedy_modularity_communities (nxG2);myDataType =类(communitiesL)
myDataType = ' py.list '
返回的Python列表包含三个元素。这意味着算法在此图中检测到3个社区。
num_communitieis =长度(communitiesL)
num_communitieis = 3.
的列表包含一个frozenset.一个蟒蛇frozenset与python相同集,除了它的元素是不可变的。和一个Python集类似于Python列表,除了所有元素都是唯一的,而a列表可以多次包含相同的元素。
ListContent = Communitiesl {1}
listContent = Python frozenset没有属性。Frozenset ({32, 33, 8, 14, 15, 18, 20, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31})
让我们把它转换成嵌套细胞.
communitiesC =细胞(communitiesL);@(x) cell(py.list(x)), communtiesc,“UniformOutput”、假);myDataType =类(communitiesC {1} {1})
myDataType = ' py.int '
最内心的细胞包含Pythonint值。让我们转换为双倍的.
为II = 1:长度(社区)Communitiesc {II} = Cellfun(@Double,Communitiesc {II});结束myDataType =类(communitiesC {1} (1))
myDataType =“双”
由于节点是基于0的索引,因此我们需要将其更改为基于Matlab的1.索引。
communtiesc = cellfun(@(x) x + 1, communtiesc,“UniformOutput”、假);
让我们在图中画出社区。
tiledlayout(1,2)nextdile p1 = plot(g);突出显示(P1,Group_hi,'nodeColor',“# D95319”,“EdgeColor”,“# D95319”)标题({圣扎迦利”年代空手道俱乐部,“橙色代表了Hi先生的派系”}) nexttile P2 = plot(G);突出(P2, communitiesC {1},'nodeColor','#0072bd',“EdgeColor”,'#0072bd')突出(P2, communitiesC {2},'nodeColor',“# D95319”,“EdgeColor”,“# D95319”)突出(P2, communitiesC {3},'nodeColor',“# 77 ac30”,“EdgeColor”,“# 77 ac30”)标题({圣扎迦利”年代空手道俱乐部,“Modularity-based社区”})
如果你比较这些图,你可以看到右边橙色和绿色的两个社区,合并后,大致与Hi先生的阵营重叠。
我们还可以看到:
- 社区1代表“军官”派系
- 社区3代表着忠诚的“Mr. Hi”派
- 社区2代表与派系有关的人
有趣的是,社区2最终最终与嗨派别的派系先生结束了。
让我们看看算法的输出和实际派别之间是否有任何不同。
diff_elements = setdiff(group_hi, [communtiesc {2} communtiesc {3}]);diff_elements = [diff_elements setdiff([communtiesc {2} communtiesc {3}], group_hi)]
10
社区检测算法非常接近识别实际派系。
精简的代码
到目前为止,我们一直在研究每一步返回的数据类型。如果您已经知道数据类型,那么您可以将许多这些步骤合并到几行代码中。
要获取空手道俱乐部数据并创建一个MATLAB图形,可以执行以下操作:
nxG = py.networkx.karate_club_graph ();@cell, cell(py.list(nxG.edges)),“UniformOutput”、假);nodeC = cellfun(@cell, cell(py.list(nxg .node .data)),“UniformOutput”、假);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 = (s, t);G.Nodes.club = nodeAttrs ';
要从MATLAB数据创建Python图,可以执行以下操作:
nxg2 = py.networkx.graph();EDGEL = NUM2CELL(INT8(G.EDGES.ENDNODE) - 1);nxg2.add_edges_from(py.list(num2cell(edgel,2)'));attrsD = py.dict;为II = 1:长度(g.nodes.club)attrd = py.dict(pyargs(“俱乐部”G.Nodes.club (ii)));attrsD.update (py。元组({{int8(ii - 1), attrD}}))结束py.networkx.set_node_attributes (nxG2 attrsD);
为了检测社区,你可以这样做:
communitiesC =细胞(py.networkx.algorithms.community.greedy_modularity_communities (nxG2));@(x) cell(py.list(x)), communtiesc,“UniformOutput”、假);为II = 1:长度(社区)Communitiesc {II} = Cellfun(@Double,Communitiesc {II});结束communtiesc = cellfun(@(x) x + 1, communtiesc,“UniformOutput”、假);
总结
在这个例子中,我们看到了如何在MATLAB中使用Python。一旦您理解了数据类型转换是如何工作的,这就相当简单了。事情要记住:
- Python是基于0的索引,而MATLAB是基于1的索引
- Python的默认数值数据类型是int而这是双倍的对MATLAB
- 将Python数据转换为合适类型的MATLAB数组,而不是循环
- 使用细胞数组为Python列表和元组
- 使用结构体数组为Pythond
在这个例子中,我们在MATLAB工作流中使用了一个Python库来获取数据并检测社区。我可以用MATLAB编写所有的代码,但是利用现有的Python代码更容易,而且我能够在熟悉的MATLAB环境中完成我的任务,在那里我可以最有生产力。
你是一名通晓多国语言的编码人员吗?分享你如何一起使用MATLAB和Python在这里.
评论
请点击留下评论在这里登录到你的MathWorks帐户或创建一个新的。