我目前正在尝试在一个非常大的矩阵(大约400x300个元素)中选择0的子集并将它们的值更改为1.我能够这样做,但它需要使用一个循环,其中每个实例选择它randperm矢量中的下一个值。换句话说,矩阵中0的50%是随机选择的,一次一个,并改为1:
z=1;
for z=1:(.5*numberofzeroes)
A(zeroposition(rpnumberofzeroes(z),1),zeroposition(rpnumberofzeroes(z),2))=1;
z=z+1;
end
其中'A'是矩阵,'zeroposition'是一个2列宽的矩阵,矩阵中的0的位置(如果你喜欢,则为“坐标”),'rpnumberofzeros'是一个randperm向量1到矩阵中的零个数。
例如,对于z = 20,代码可能是这样的:
A(3557,2684)= 1;
...以便A中此位置出现的0现在为1。
它执行此循环数千次,因为.5 * numberofzeroes是一个非常大的数字。这不可避免地需要很长时间,所以我的问题是这可以在不使用循环的情况下完成吗?或者至少在某种程度上减少了处理资源/时间?
正如我所说,唯一需要做的就是完全随机选择50%(或任何比例)的0变为1。
提前感谢您的帮助,如果我能搞清楚的话,请告诉我!我是新来的,如果我做了任何仿制品,请提前道歉。
答案 0 :(得分:0)
这很容易。我想把你介绍给我的朋友sub2ind
。 sub2ind
允许您获取矩阵的行和列坐标,并将它们转换为线性列主索引,以便您可以在单个调用中同时访问矩阵中的多个值。因此,您想要的等效代码是:
%// First access the values in rpnumberofzeroes
vals = rpnumberofzeroes(1:0.5*numberofzeroes, :);
%// Now, use the columns of these to determine which rows and columns we want
%// to access A
rows = zeroposition(vals(:,1), 1);
cols = zeroposition(vals(:,2), 2);
%// Get linear indices via sub2ind
ind1 = sub2ind(size(A), rows, cols);
%// Now set these locations to 1
A(ind1) = 1;
第一个语句获取存储在rpnumberofzeroes
中的坐标矩阵的前半部分。第一列是行坐标,第二列是列坐标。请注意,在您的代码中,您希望使用zeroposition
中的值来访问A
中的位置。因此,从rpnumberofzeroes
中提取出相应的行和列,以便从zeroposition
中找出正确的行和列。完成后,我们希望使用zeroposition
中的这些新行和列,并将其编入A
。 sub2ind
需要三个输入 - 您尝试访问的矩阵的大小...所以在我们的例子中,A
,行坐标和列坐标。输出是一组列主要索引,为每个行和列对计算。
最后一个难题是使用它们来索引A
并将位置设置为1.
答案 1 :(得分:0)
这也可以通过线性索引完成:
% find linear position of all zeros in matrix
ix=find(abs(A)<eps);
% set one half of those, selected at random, to one.
A(ix(randperm(round(numel(ix)*.5)))=1;