Bra*_*ley 1 python arrays iteration matlab numpy
假设您在MATLAB中有以下代码:
[xi yi imv] = find(imagee+0.1);
imv = imv - 0.1;
wv = abs(imv*ones(1,length(imv)) - ones(length(imv),1)*imv');
Run Code Online (Sandbox Code Playgroud)
并且您希望在Python中实现此代码.Imagee是一个预定义的合成图像,由10x10数组表示,值为0,1,2.实现这一目标的最有效方法是什么?我知道你可以迭代地遍历整个矩阵并随时修改值,但我确信python的方法比这更快.
编辑:澄清imagee :(我已经把它翻译成python)
C= np.zeros((L,L), int)
C[:L/2,:L/2]=1
C[L/2:L,:L/2]=2
Run Code Online (Sandbox Code Playgroud)
我看到你已经在使用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]])
Run Code Online (Sandbox Code Playgroud)
现在,让我们一次一个地浏览每一行.
[xi yi imv] = find(imagee+0.1);
Run Code Online (Sandbox Code Playgroud)
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])
Run Code Online (Sandbox Code Playgroud)
如果你在MATLAB中做了相同的操作,你会发现imv
在Python和MATLAB中都给出了相同的值顺序.
imv = imv - 0.1;
Run Code Online (Sandbox Code Playgroud)
这很简单:
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.])
Run Code Online (Sandbox Code Playgroud)
wv = abs(imv*ones(1,length(imv)) - ones(length(imv),1)*imv');
Run Code Online (Sandbox Code Playgroud)
本声明的第一部分(在abs
调用内)是执行两个向量的外积.在MATLAB中,imv
将是N x 1
,并且您将它与一个1 x N
向量相乘.您可以使用它numpy.outer
来帮助您执行此外部产品步骤.请注意,对于1D数组,numpy
不区分行向量和列向量,因此将向量与另一个向量相乘可能不会给出您期望的结果.但是,如果您需要此行为,则必须显式定义单个维度为1(行或列)的2D矩阵,但是让我们将此放在此帖子中.
本声明的第二部分也执行外部产品,但是在声明第一部分的转置版本上.
因此:
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.]])
Run Code Online (Sandbox Code Playgroud)
为方便起见,代码的第一部分声明了一个向量.之后,我们计算你想要的东西.
希望这可以帮助!