从 MATLAB 到 Python 的无迭代实现
Implementation from MATLAB to Python without iterations
假设您在 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 有比这更快的方法。
编辑:澄清图像:(我已经将其翻译成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 将 return 这些值 列优先 顺序,而 numpy
将在 [=64] 中执行相同的操作=]行优先顺序。如果您想在 Python 中复制相同的行为,您需要先 转置 矩阵。因此,为了方便起见,我将创建一个转置 imagee
并为每个条目添加 0.1 的新矩阵。但是,我有点困惑,因为如果 imagee
已经包含 0,1,2
,如果您将此矩阵中的每个值都加上 0.1,imv
将 return all imagee+0.1
中的值...这对我来说似乎毫无意义。不过,您可以使用 numpy.nonzero
为您提供非零元素的位置。一旦你找到这些非零元素,你可以简单地索引到 C
添加 0.1
的转置以获得你想要的值。 numpy.nonzero
将 return 一个包含两个元素的元组,其中第一个元素是一个数组,告诉您 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 of two vectors. In MATLAB, imv
would be N x 1
, and you are multiplying this with a 1 x N
vector of ones. You can use numpy.outer
以帮助您执行此外积步骤。请注意,对于一维数组,numpy
不区分行向量和列向量,因此不幸的是,将一个向量与另一个向量的转置相乘不会得到您期望的结果。但是,如果您想要这种行为,则必须显式定义一个二维矩阵,其单维度为 1(行或列),但我们将其放在一边 post.
此语句的第二部分也执行外积,但在语句第一部分的转置版本上。
因此:
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.]])
为了方便起见,代码的第一部分声明了一个向量。之后,我们计算你想要的。
希望对您有所帮助!
假设您在 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 有比这更快的方法。
编辑:澄清图像:(我已经将其翻译成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 将 return 这些值 列优先 顺序,而 numpy
将在 [=64] 中执行相同的操作=]行优先顺序。如果您想在 Python 中复制相同的行为,您需要先 转置 矩阵。因此,为了方便起见,我将创建一个转置 imagee
并为每个条目添加 0.1 的新矩阵。但是,我有点困惑,因为如果 imagee
已经包含 0,1,2
,如果您将此矩阵中的每个值都加上 0.1,imv
将 return all imagee+0.1
中的值...这对我来说似乎毫无意义。不过,您可以使用 numpy.nonzero
为您提供非零元素的位置。一旦你找到这些非零元素,你可以简单地索引到 C
添加 0.1
的转置以获得你想要的值。 numpy.nonzero
将 return 一个包含两个元素的元组,其中第一个元素是一个数组,告诉您 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 of two vectors. In MATLAB, imv
would be N x 1
, and you are multiplying this with a 1 x N
vector of ones. You can use numpy.outer
以帮助您执行此外积步骤。请注意,对于一维数组,numpy
不区分行向量和列向量,因此不幸的是,将一个向量与另一个向量的转置相乘不会得到您期望的结果。但是,如果您想要这种行为,则必须显式定义一个二维矩阵,其单维度为 1(行或列),但我们将其放在一边 post.
此语句的第二部分也执行外积,但在语句第一部分的转置版本上。
因此:
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.]])
为了方便起见,代码的第一部分声明了一个向量。之后,我们计算你想要的。
希望对您有所帮助!