Skip to main content
 首页 » 编程设计

python之从 MATLAB 到 Python 的无迭代实现

2025年05月04日54dyllove98

假设您在 MATLAB 中有以下代码:

    [xi yi imv] = find(imagee+0.1); 
    imv = imv - 0.1; 
    wv = abs(imv*ones(1,length(imv)) - ones(length(imv),1)*imv'); 

并且您想在 Python 中实现此代码。 Imagee 是预定义的合成图像,由值为 0、1、2 的 10x10 数组表示。完成此任务的最有效方法是什么?我知道您可以迭代遍历整个矩阵并随时修改值,但我确信 python 有比这更快的方法。

编辑:澄清imagee:(我已经将其翻译成python)

    C= np.zeros((L,L), int) 
    C[:L/2,:L/2]=1 
    C[L/2:L,:L/2]=2 

请您参考如下方法:

我看到您已经在使用 numpy,这是朝着正确方向迈出的一步。现在,让我们一次一个地检查每个语句,并获得与您所追求的等效的 numpy。它表示您的矩阵是 10 x 10,因此我假设 L = 10。下面是我们将要开始的(在 IPython 中):

In [2]: import numpy as np 
 
In [3]: L = 10 
 
In [4]: C= np.zeros((L,L), int) 
 
In [5]: C[:L/2,:L/2]=1 
 
In [6]: C[L/2:L,:L/2]=2 
 
In [7]: C 
Out[7]: 
array([[1, 1, 1, 1, 1, 0, 0, 0, 0, 0], 
       [1, 1, 1, 1, 1, 0, 0, 0, 0, 0], 
       [1, 1, 1, 1, 1, 0, 0, 0, 0, 0], 
       [1, 1, 1, 1, 1, 0, 0, 0, 0, 0], 
       [1, 1, 1, 1, 1, 0, 0, 0, 0, 0], 
       [2, 2, 2, 2, 2, 0, 0, 0, 0, 0], 
       [2, 2, 2, 2, 2, 0, 0, 0, 0, 0], 
       [2, 2, 2, 2, 2, 0, 0, 0, 0, 0], 
       [2, 2, 2, 2, 2, 0, 0, 0, 0, 0], 
       [2, 2, 2, 2, 2, 0, 0, 0, 0, 0]]) 

现在,让我们一次一行地检查每一行。


[xi yi imv] = find(imagee+0.1); 

imv 基本上为您提供了 imagee+0.1 中所有非零值的向量。但是,您需要记住的是,MATLAB 将返回这些值按列优先顺序,而 numpy 将按行优先 <执行相同的操作 strong> 命令。如果您想在 Python 中复制相同的行为,您需要先 转置矩阵。因此,为了方便起见,我将创建一个转置 imagee 并向每个条目添加 0.1 的新矩阵。但是,我有点困惑,因为如果 imagee 已经包含 0,1,2,如果您将此矩阵中的每个值都加上 0.1, imv 将返回 imagee+0.1 中的 所有 值....这对我来说似乎毫无意义。不过,您可以使用 numpy.nonzero给你非零元素的位置。一旦你找到这些非零元素,你可以简单地索引到 C 添加了 0.1 的转置来获得你想要的值。 numpy.nonzero 将返回一个包含两个元素的元组,其中第一个元素是一个数组,告诉您那些在 C+0.1 中非零值的行位置和第二个元素是一个数组,告诉您在 C+0.1 中非零的列位置:

In [9]: CT = C.T + 0.1 
 
In [10]: ind = CT.nonzero() 
 
In [11]: imv = CT[ind[0], ind[1]] 
 
In [12]: imv 
Out[12]: 
array([ 1.1,  1.1,  1.1,  1.1,  1.1,  2.1,  2.1,  2.1,  2.1,  2.1,  1.1, 
    1.1,  1.1,  1.1,  1.1,  2.1,  2.1,  2.1,  2.1,  2.1,  1.1,  1.1, 
    1.1,  1.1,  1.1,  2.1,  2.1,  2.1,  2.1,  2.1,  1.1,  1.1,  1.1, 
    1.1,  1.1,  2.1,  2.1,  2.1,  2.1,  2.1,  1.1,  1.1,  1.1,  1.1, 
    1.1,  2.1,  2.1,  2.1,  2.1,  2.1,  0.1,  0.1,  0.1,  0.1,  0.1, 
    0.1,  0.1,  0.1,  0.1,  0.1,  0.1,  0.1,  0.1,  0.1,  0.1,  0.1, 
    0.1,  0.1,  0.1,  0.1,  0.1,  0.1,  0.1,  0.1,  0.1,  0.1,  0.1, 
    0.1,  0.1,  0.1,  0.1,  0.1,  0.1,  0.1,  0.1,  0.1,  0.1,  0.1, 
    0.1,  0.1,  0.1,  0.1,  0.1,  0.1,  0.1,  0.1,  0.1,  0.1,  0.1, 
    0.1]) 

如果您在 MATLAB 中执行相同的操作,您会注意到 Python 和 MATLAB 中的 imv 给出相同的值顺序。


imv = imv - 0.1; 

这很简单:

In [22]: imv = imv - 0.1 
 
In [23]: imv 
Out[23]: 
array([ 1.,  1.,  1.,  1.,  1.,  2.,  2.,  2.,  2.,  2.,  1.,  1.,  1., 
        1.,  1.,  2.,  2.,  2.,  2.,  2.,  1.,  1.,  1.,  1.,  1.,  2., 
        2.,  2.,  2.,  2.,  1.,  1.,  1.,  1.,  1.,  2.,  2.,  2.,  2., 
        2.,  1.,  1.,  1.,  1.,  1.,  2.,  2.,  2.,  2.,  2.,  0.,  0., 
        0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0., 
        0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0., 
        0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0., 
        0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.]) 

wv = abs(imv*ones(1,length(imv)) - ones(length(imv),1)*imv'); 

此语句的第一部分(在 abs 调用内)执行 outer product的两个向量。在 MATLAB 中,imv 将是 N x 1,您将其与 1 x N 向量相乘。您可以使用 numpy.outer帮助你做这个外积步骤。请注意,对于一维数组,numpy 不区分行向量和列向量,因此不幸的是,将一个向量与另一个向量的转置相乘不会得到您期望的结果。但是,如果您想要这种行为,则必须显式定义一个二维矩阵,其单维度为 1(行或列),但在本文中我们将其搁置一旁。

此语句的第二部分也执行外积,但在语句第一部分的转置版本上。

因此:

In [24]: ones_vector = np.ones(len(imv)) 
 
In [25]: wv = np.abs(np.outer(imv, ones_vector) - np.outer(ones_vector, imv)) 
 
In [26]: wv 
Out[26]: 
array([[ 0.,  0.,  0., ...,  1.,  1.,  1.], 
   [ 0.,  0.,  0., ...,  1.,  1.,  1.], 
   [ 0.,  0.,  0., ...,  1.,  1.,  1.], 
   ..., 
   [ 1.,  1.,  1., ...,  0.,  0.,  0.], 
   [ 1.,  1.,  1., ...,  0.,  0.,  0.], 
   [ 1.,  1.,  1., ...,  0.,  0.,  0.]]) 

为方便起见,代码的第一部分声明了一个向量。之后,我们会计算您想要什么。


希望这对您有所帮助!