我想根据向量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秒。
你能更快地提出建议吗?
答案 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
仅支持向量输入,因此我们使用A
将A(:)
展平为列向量。然后我们还需要制作第二个输入(重复A
的每个元素的次数),以便我们为counts
的每一列重复A
。
nTimes = repmat(counts(:), size(A, 2), 1)
然后我们使用repelem
来执行重复
repeated = repelem(A(:), nTimes);
然后我们将结果重新整形为具有正确的列数
reshape(repeated, [], size(A, 2))
答案 1 :(得分:0)
基于group by
和id
的解决方案:
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