简体   繁体   English

使用不同的输入将repmat应用于Matlab中矩阵的每一行

[英]Applying repmat to each row of a matrix in Matlab with different inputs

I want to stack each row of a matrix A in Matlab a different number of times according to what is reported in the vector count . 我想根据向量count报告的内容,在Matlab中将矩阵A的每一行堆叠不同的次数。 To do that I use repmat in the following way: 为此,我使用以下方式使用repmat

counts=[524282; 524286; 524283; 524290];
A=randn(4,19); 
f=@() cell2mat(arrayfun(@(x) repmat(A(x,:),counts(x),1), 1:size(counts,1), 'UniformOutput', 0)');
timeit(f)

The code takes approx 0.45 sec. 代码大约需要0.45秒。

Would you be able to suggest anything faster? 你能更快地提出建议吗?

You could use repelem to repeat each element in the initial matrix a particular number of times 您可以使用repelem重复初始矩阵中的每个元素特定次数

result = reshape(repelem(A(:), repmat(counts(:), size(A, 2), 1)), [], size(A, 2));

Explanation 说明

A = [1, 2, 3; 4, 5, 6; 7, 8, 9];
counts = [1, 3, 2];

repelem (for vector inputs), repeats the ith element of the first input the number of times specified in the corresponding element of the second input. repelem (对于向量输入),重复第一个输入的第i个元素,在第二个输入的相应元素中指定的次数。

repelem([1, 2, 3], [3, 4, 1])
%     1     1     1     2     2     2     2     3

Since repelem only supports vector inputs, we flatten A into a column vector using A(:) . 由于repelem仅支持矢量输入,我们弄平A使用成列向量A(:) We also then need to craft the second input (the number of times to repeat each element of A ) such that we repeat counts for each column of A . 然后我们还需要制作第二个输入(重复A每个元素的次数),以便我们重复A每一列的counts

nTimes = repmat(counts(:), size(A, 2), 1)

We then use repelem to perform the repetition 然后我们使用repelem来执行重复

repeated = repelem(A(:), nTimes);

We then reshape the result to have the correct number of columns 然后,我们将结果重新整形为具有正确的列数

reshape(repeated, [], size(A, 2))

A solution base on diff and cumsum : 基于diffcumsum解决方案:

co = size(A,2);
A_diff=diff([zeros(1,co);A]);
idx=cumsum([1;counts(1:end-1)]);
result=zeros(sum(counts),co);
result(idx,:)=A_diff;
result = cumsum(result)

The idea is using cumsum we can reconstruct a vector form the first difference of it. 这个想法是使用cumsum我们可以重建一个矢量形式,它的第一个区别。

a=[5 3 2 4];
d=  diff([0 a]);
out = cumsum(d)

So out is equal to a . 所以out等于a

We can make a matrix all of zeros of the desired size: 我们可以制作一个所需大小为零的矩阵:

result=zeros(sum(count),co);

we should find indices of rows of each section 我们应该找到每个部分的行索引

idx=cumsum([1;count(1:end-1)]);

set the first row of each section to first difference of the matrix A 将每个部分的第一行设置为矩阵A第一个差异

A_diff=diff([zeros(1,co);A]);
result(idx,:)=A_diff;

so 所以

A = randi(4,4,7);
count=[3 ;4 ;2 ;5];
A =

   2   1   4   2   1   3   1
   2   3   2   4   4   3   2
   1   3   1   4   1   2   1
   2   3   2   2   3   1   2

A_diff =

   2   1   4   2   1   3   1
   0   2  -2   2   3   0   1
  -1   0  -1   0  -3  -1  -1
   1   0   1  -2   2  -1   1

result =

   2   1   4   2   1   3   1
   0   0   0   0   0   0   0
   0   0   0   0   0   0   0
   0   2  -2   2   3   0   1
   0   0   0   0   0   0   0
   0   0   0   0   0   0   0
   0   0   0   0   0   0   0
  -1   0  -1   0  -3  -1  -1
   0   0   0   0   0   0   0
   1   0   1  -2   2  -1   1
   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

apply cumsum to it to get the desired result cumsum应用于它以获得所需的结果

result = cumsum(result)
result =

   2   1   4   2   1   3   1
   2   1   4   2   1   3   1
   2   1   4   2   1   3   1
   2   3   2   4   4   3   2
   2   3   2   4   4   3   2
   2   3   2   4   4   3   2
   2   3   2   4   4   3   2
   1   3   1   4   1   2   1
   1   3   1   4   1   2   1
   2   3   2   2   3   1   2
   2   3   2   2   3   1   2
   2   3   2   2   3   1   2
   2   3   2   2   3   1   2
   2   3   2   2   3   1   2

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM