python - 如何在 Python 3 中转换 MATLAB 单元格?

标签 python matlab numpy scipy

只是为了给您一些背景信息:

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

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 代码中还有第三个循环:

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

这也有点......让我心烦意乱?

事实是我真的不知道如何将这种变量翻译成Python。另外,我猜我的 Python 代码有点“损坏” - 并且我并不是真的要求你们任何人改进它 - 所以我只是问哪一个是最好的如何将Matlab的单元格翻译成Python?

<小时/>

我终于找到了一些显然简单的东西来翻译这个,使用列表理解 - 根据kazemakase的答案。实际的 Python 代码现在如下所示:

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())]

输出中看起来像这样:

[[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(...)]]

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

最佳答案

您需要问的第一个问题是“什么是 Matlab 单元以及什么可能是合适的相应 Python 类型?”

如果我没记错的话,在我糟糕的过去的 Matlab 岁月里,单元格是一种容纳混合类型内容的容器。它类似于动态类型的数组或矩阵。它是多维索引的。

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

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

对于特定场景,字典可以更好地反射(reflect) Matlab 语法。虽然字典只需要一个索引,但我们可以利用这样一个事实:元组可以在没有括号的情况下声明,并且字典可以将元组作为索引:

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 代码不同。选择取决于性能或与原始代码的相似性。但如果性能是一个问题,那么无论如何还有很多事情需要考虑。总之:没有一种最好的方法。

<小时/>

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

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

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

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

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

现在,为了我灵魂的平静,让我分解提供有关OP代码的反馈:

k_topology = [[]]
for i in range(x):
    for i in range(x):
        k_topology[[i][j]].extend(np.zeros(3,3))
  1. 这与原始Matlab代码无关(变量名称不同)
  2. 两个循环都使用ij 从未定义。
  3. [[i][j]] 使用一个元素 i 构建一个列表,并尝试获取第 j 个元素。如果 j 不是 0,这将导致错误。
  4. list.extend a 将参数的所有元素单独附加到列表中 - 在本例中为单独的行。 list.append 使用起来是正确的,因为整个 3x3 矩阵应作为一个元素附加到 K 中。
  5. np.zeros(3, 3) 应为 np.zeros((3, 3)) (假设 np 是别名对于numpy),因为该函数采用的形状是第一个参数,而不是多个参数。

关于python - 如何在 Python 3 中转换 MATLAB 单元格?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42252785/

相关文章:

python - 使用 Numpy 和 Matplotlib 绘制具有多个数据值的图表

python - Seaborn 箱线图,所有箱子颜色相同

python - 在 Python 中将所有数组元素转换为范围

python - django 模板中的自定义计数器

matlab - 如何从 Matlab 环境执行 OpenSMILE 工具包?

matlab - 使用Matlab工具箱或opencv2进行立体相机校准

matlab - 频率增加的 Simulink 正弦波

python - 检查数组中的元素是否存在于 Pandas DataFrame 中

python - 检查 Pandas 系列是否至少有一项大于某个值

python - pysftp 无法创建日志文件 - 权限被拒绝