我想控制在这个矩阵中创建随机数:
Mp = floor(1+(10*rand(2,20)));
mp1 = sort(Mp,2);
我想修改此代码以获得如下输出:
1 1 2 2 3 3 3 4 5 5 6 7 7 8 9 9 10 10 10 10
1 2 3 3 3 3 3 3 4 5 6 6 6 6 7 8 9 9 9 10
我必须以递增的顺序填充每一行的所有数字从1到10,并且计算每个数字出现次数的第二个矩阵应该是这样的:
1 2 1 2 1 2 3 1 1 2 1 1 2 1 1 2 1 2 3 4
1 1 1 2 3 4 5 6 1 1 1 2 3 4 1 1 1 2 3 1
和我上周以来一直在寻找的最棘手的矩阵是第三个矩阵,它应该浏览第一个矩阵的每一行,并返回每个数字的出现次数和最后一次出现的位置。这是代码应该如何工作的一个例子。此示例显示了在遍历第一个矩阵的第一行之后的预期结果。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 (positions)
1 2
2 2
3 3
4 1
5 2
6 1
7 2
8 1
9 2
10 4
(数)
此示例显示了在遍历第一个矩阵的第二行之后的预期结果。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 (positions)
1 1 2
2 1 2
3 3 6
4 1 1
5 3
6 1 4
7 2 1
8 1 1
9 2 3
10 4
(数)
所以想要的矩阵必须从头开始用零填充,每次在遍历第一个矩阵的每一行之后,我们将新结果添加到前一个...
答案 0 :(得分:0)
我相信以下代码会执行您要求的所有内容。如果我不明白,你需要更清楚地提出你的问题......
注意 - 我硬编码了一些值/大小。在“真实代码”中,你显然永远不会这样做。
% the bit of code that generates and sorts the initial matrix:
Mp = floor(1+(10*rand(2,20)));
mp1 = sort(Mp, 2);
clc
disp(mp1)
occCount = zeros(size(mp1));
for ii = 1:size(mp1,1)
for jj = 1:size(mp1,2)
if (jj == 1)
occCount(ii,jj) = 1;
else
if (mp1(ii,jj) == mp1(ii,jj-1))
occCount(ii,jj) = occCount(ii, jj-1) + 1;
else
occCount(ii,jj) = 1;
end
end
end
end
% this is the second matrix you asked for
disp(occCount)
% now the third:
big = zeros(10, 20);
for ii = 1:size(mp1,1)
for jj = 1:10
f = find(mp1(ii,:) == jj); % index of all of them
if numel(f) > 0
last = f(end);
n = numel(f);
big(jj, last) = big(jj, last) + n;
end
end
end
disp(big)
请查看这确实是您的想法。
答案 1 :(得分:0)
我正在编辑上一个答案,以检查当mp1很大时它是否很快,显然它是:
N = 20000; M = 200; P = 100;
mp1 = sort([repmat(1:P, M, 1), ceil(P*rand(M,N-P))], 2);
tic
% Initialise output matrices
out1 = zeros(M, N); out2 = zeros(P, N);
for gg = 1:M
% Frequencies of each row
freqs(:, 1) = mp1(gg, [find(diff(mp1(gg, :))), end]);
freqs(:, 2) = histc(mp1(gg, :), freqs(:, 1));
cumfreqs = cumsum(freqs(:, 2));
k = 1;
for hh = 1:numel(freqs(:, 1))
out1(gg, k:cumfreqs(hh)) = 1:freqs(hh, 2);
out2(freqs(hh, 1), cumfreqs(hh)) = out2(freqs(hh, 1), cumfreqs(hh)) + freqs(hh, 2);
k = cumfreqs(hh) + 1;
end
end
toc
答案 2 :(得分:0)
以下代码通过单个循环解决了第二个和第三个矩阵生成问题。为清楚起见,第二个矩阵M2
是示例中包含累积发生次数的2-by-20
数组。第三个矩阵M3
是示例中的大小为10-by-20
的稀疏矩阵,其对每个唯一值的最后一次出现的数量和位置进行编码。代码仅循环遍历行,使用accumarray
完成大部分工作。它被推广到mp1
的任何大小和内容,只要首先对行进行排序。
% data
mp1 = [1 1 2 2 3 3 3 4 5 5 6 7 7 8 9 9 10 10 10 10;
1 2 3 3 3 3 3 3 4 5 6 6 6 6 7 8 9 9 9 10]; % the example first matrix
nuniq = max(mp1(:));
% accumulate
M2 = zeros(size(mp1));
M3 = zeros(nuniq,size(mp1,2));
for ir=1:size(mp1,1),
cumSums = accumarray(mp1(ir,:)',1:size(mp1,2),[],@numel,[],true)';
segments = arrayfun(@(x)1:x,nonzeros(cumSums),'uni',false);
M2(ir,:) = [segments{:}];
countCoords = accumarray(mp1(ir,:)',1:size(mp1,2),[],@max,[],true);
[ii,jj] = find(countCoords);
nzinds = sub2ind(size(M3),ii,nonzeros(countCoords));
M3(nzinds) = M3(nzinds) + nonzeros(cumSums);
end
我不会打印输出,因为它们对于答案来说有点大,而且代码可以按原样运行。
注意:对于新的测试数据,我建议使用命令Mp = randi(10,[2,20]); mp1 = sort(Mp,2);
。或者根据您对user2875617的请求及其回复,确保所有号码都为mp1 = sort([repmat(1:10,2,1) randi(10,[2,10])],2);
但不是真的随机...
编辑:代码修复错误。