将repmat应用于Matlab中具有不同输入

时间:2017-03-22 15:25:23

标签: matlab

我想根据向量count中报告的内容,在Matlab中将矩阵A的每一行堆叠不同次。为此,我按以下方式使用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)

代码大约需要0.45秒。

你能更快地提出建议吗?

2 个答案:

答案 0 :(得分:3)

您可以使用repelem重复初始矩阵中的每个元素特定次数

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

<强>解释

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

repelem(对于向量输入),重复第一个输入的第i个元素,在第二个输入的相应元素中指定的次数。

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

由于repelem仅支持向量输入,因此我们使用AA(:)展平为列向量。然后我们还需要制作第二个输入(重复A的每个元素的次数),以便我们为counts的每一列重复A

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

然后我们使用repelem来执行重复

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

然后我们将结果重新整形为具有正确的列数

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

答案 1 :(得分:0)

基于group byid的解决方案:

diff

这个想法是使用cumsum,我们可以从它的第一个区别重建一个向量。

cumsum

所以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) 等于a=[5 3 2 4]; d= diff([0 a]); out = cumsum(d)

我们可以制作一个所需大小为零的矩阵:

out

我们应该找到每个部分的行索引

a

将每个部分的第一行设置为矩阵result=zeros(sum(count),co);

的第一个差异
idx=cumsum([1;count(1:end-1)]);

所以

A

对其应用A_diff=diff([zeros(1,co);A]); result(idx,:)=A_diff; 以获得所需的结果

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