如何在Python 3中转换MATLAB单元? [英] How can I translate a MATLAB cell in Python 3?

查看:109
本文介绍了如何在Python 3中转换MATLAB单元?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

只为您提供一些背景信息:

我必须将一些MATLAB代码转换为Python 3,但是在这里我遇到了一个小问题.

I have to translate some MATLAB code into Python 3 one, but here I've been confronted to a little problem.

Matlab:

for i in 1:num_nodes
    for j in 1:num_nodes
        K{i,j} = zeros(3,3);

我翻译成:

k_topology = [[]]
for i in range(x):
    for i in range(x):
        k_topology[[i][j]].extend(np.zeros(3,3))

此外,在Matlab代码中,还有第三个循环:

Also, further in the Matlab code there's a third loop:

for k in 1:3
    K{i,j}(k,k) = -1

还有什么...让我难过?

Which also kind of... Upsets me?

事实是,我真的不明白如何将这种变量转换为Python.另外,我想我的Python代码有点破损"-,我并不是真的要求任何人对其进行改进-,所以我只是问哪一个是最好的将Matlab的单元格转换成Python的方法?

The fact is I don't really see how I can translate this kind of variable into Python. Also, I guess that my Python code's kind of "broken" - and I'm not really asking to any of you to improve it - , so I'm just asking which is the best way to translate Matlab's cell into Python?

我终于找到了很显然的东西,可以使用列表理解-根据kazemakase的答案 来翻译.实际的Python代码现在看起来像这样:

I finally found something apparently simple to translate this, using list comprehension - according to kazemakase's answer. The actual Python code is now looking like this:

k_topology = [[np.zeros((3,3)) for j in range(self.get_nb_nodes_from_network())]\
                  for i in range(self.get_nb_nodes_from_network())]

在输出中看起来像这样:

And looks like something like this in Output:

[[array([[ 0.,  0.,  0.],
       [ 0.,  0.,  0.],
       [ 0.,  0.,  0.]]), 
array([[ 0.,  0.,  0.],
       [ 0.,  0.,  0.],
       [ 0.,  0.,  0.]]), 
array([[ 0.,  0.,  0.],
       [ 0.,  0.,  0.],
       [ 0.,  0.,  0.]])], ..., [array(...)]]

(确实有太多值无法将其粘贴到此处,但我想您已经明白了.)

(There's really too many values to paste it here, but I think you got it.)

推荐答案

您需要问的第一个问题是什么 是Matlab单元,什么是合适的对应Python类型?"

The first question you need to ask is "what is a Matlab cell and what could be a suitable corresponding Python type?"

如果我在过去的Matlab年代过得很不好,那我可以正确地记住单元格就是一个容纳混合类型内容的容器.它类似于动态类型的数组或矩阵.它是多维索引的.

If I remember correctly from my bad old Matlab days, a cell is sort of a container that holds content of mixed types. It is something like a dynamically typed array or matrix. It is multidimensionally indexed.

Python是动态类型的,因此任何Python容器都可以基本实现此功能. Python中的列表已建立索引,因此嵌套列表可以工作-但设置和访问它们有点怪异:

Python is dynamically typed, so any Python contianer can basically fulfill this function. Lists in Python are indexed, so nested lists could work - but they are somewhat weird to set up and access:

K = [[None] * num_nodes  for _ in range(num_nodes)]
K[i][j]  # need two indices to access elements of a nested list.

对于特定的情况,字典可以更好地反映Matlab语法.尽管词典仅使用一个索引,但我们可以利用以下事实:可以在不使用方括号的情况下声明元组,并且词典可以将元组作为索引:

For the particular scenario a dictionary better mirrors Matlab syntax. Although a ditionary takes only one index, we can exploit the fact that tuples can be declared without brackets and that dictionaries can take tuples as index:

K = {}
for i in range(num_nodes):
    for j in range(num_nodes):
        K[i, j] = np.zeros((3, 3))

        for k in 1:3
            K[i, j][k, k] = -1

虽然字典在语法上更加简洁,但是元素访问的性能可能比嵌套列表中的性能差.嵌套外观与Matlab代码不同.选择取决于性能或与原始代码的相似性.但是,如果性能是一个问题,无论如何,还有很多事情要考虑.总结:没有最好的方法.

While the dictionary is syntactically more concise, element access is potentially less performant than in nested lists. Nested look different than Matlab code. The choice depends on performance or similarity to the original code. But if performance is an issue there are many more things to consider, anyway. In summary: There is no one best way to do it.

由于OP明确要求不改进代码,所以我明确要求他/她忽略答案的这一部分.

Since the OP expclicitly asked not to improve the code, I explicitly ask him/her to ignore this part of the answer.

构建对角矩阵的更好方法是使用np.ones而不是循环遍历对角元素.

A better way to build diagonal matrices is to use np.ones instead of looping over diagonal elements.

K = {}
for i in range(num_nodes):
    for j in range(num_nodes):
        K[i, j] = -np.ones((3, 3))

此外,如果这是首选方法,则可以在没有(很多)事先初始化的情况下构造嵌套列表:

Also, nested lists can be constructed without (much) prior initialization, if that is the preferred approach:

K = []
for i in range(num_nodes):
    K.append([])
    for j in range(num_nodes):
        K[-1].append(-np.ones((3, 3)))


现在,为了我的灵魂安宁,让我散布提供关于OP的代码的反馈:


Now, for the peace of my soul, let me take apart provide feedback on the OP's code:

k_topology = [[]]
for i in range(x):
    for i in range(x):
        k_topology[[i][j]].extend(np.zeros(3,3))

  1. 这与原始的Matlab代码(不同的变量名称)无关
  2. 两个循环都使用i. j从未定义.
  3. [[i][j]]用一个元素i构建一个列表,并尝试采用第j个元素.如果j的值不是0,则将导致错误.
  4. list.extend a将参数的所有元素分别追加到列表-在这种情况下为单独的行. list.append可以正确使用,因为整个3x3矩阵应作为K中的一个元素附加.
  5. np.zeros(3, 3)应该为np.zeros((3, 3))(假设npnumpy的别名),因为该函数采用的形状是第一个参数,而不是多个参数.
  1. This has nothing to do with the original Matlab code (different variable names)
  2. Both loops use i. j is never defined.
  3. [[i][j]] builds a list with one element i and tries to take the jth element. If j is ever something other than 0 this will cause an error.
  4. list.extend a appends all elements of the argument individually to the list - in this case individual rows. list.append would be correct to use as the whole 3x3 matrix should be appended as one element in K.
  5. np.zeros(3, 3) should be np.zeros((3, 3)) (assuming np is an alias for numpy) because the function takes the shape is the first argument, not multiple arguments.

这篇关于如何在Python 3中转换MATLAB单元?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆