从MATLAB实现到Python没有迭代(Implementation from MATLAB to

2019-10-23 06:20发布

假设你有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是由10×10阵列的值0,1,2表示的预定义的,合成图像。 什么是解决这个问题的最有效的方法? 我知道你可以通过整个矩阵反复走,你去修改值,但我敢肯定,Python有比这更快的方法。

编辑:澄清关于imagee:(我已经翻译这蟒蛇)

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

Answer 1:

我看到你已经在使用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会做行主顺序相同的操作。 如果要复制在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相同的操作,你会发现, imv在Python和MATLAB给出值的顺序相同。


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呼叫)进行外积两个向量的。 在MATLAB中, imvN 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.]])

的代码的第一部分声明者为了方便的向量。 在那之后,我们计算你的渴望。


希望这可以帮助!



文章来源: Implementation from MATLAB to Python without iterations