这里有一个类似的问题,Element-wise array replication in Matlab,但我想稍微概括一下。简单的情况需要一个函数'replicate',它将带一个vector,a,然后用N来复制每个元素。例如。
>> a = [1, 2, 3];
>> replicate(a, 3);
ans =
[1, 1, 1, 2, 2, 2, 3, 3, 3]
>>
上述链接中有许多解决方案很有帮助。然而,N发生的是每个元素的多重性向量?例如,我想要像:
>> a = [1, 2, 3];
>> N = [3, 1, 5];
>> replicate(a,N)
ans =
[1, 1, 1, 2, 3, 3, 3, 3, 3]
>>
不幸的是,我的MATLAB-index-fu并没有达到这个水平,我无法弄清楚如何在没有循环的情况下执行此操作,比如说N,然后使用repmat将a的每个元素平铺到一个大小[N(i),1]向量。例如。我循环遍历数组数据,然后使用multcol位置的多重性值重新匹配它。数据是MCMC中的步骤,每个步骤的多重性位于最后一列。
data=[-3.997 4.402 0.000 703.050 -219.900 289.600 2.000 5.700 -49.100 11.100 3;...
-2.476 2.685 0.000 667.800 -220.210 290.000 1.955 5.710 -48.828 11.116 3; ...
-4.658 0.286 0.000 626.370 -220.420 290.380 2.019 5.991 -49.015 11.1210 2];
multcol = 11;
%unwrap the data
in=1;
for i=1:size(data,1)
data_uw(in:in+data(i,multcol)-1,:) = ...
repmat(data(i,1:multcol-1),[data(i,multcol) 1]);
in=in+data(i,multcol);
end
这有效,但相对较慢。最终结果data_uw是输入矩阵的每一行,数据,被复制多重列中的次数。
>> data_uw
data_uw =
Columns 1 through 7
-3.9970 4.4020 0 703.0500 -219.9000 289.6000 2.0000
-3.9970 4.4020 0 703.0500 -219.9000 289.6000 2.0000
-3.9970 4.4020 0 703.0500 -219.9000 289.6000 2.0000
-2.4760 2.6850 0 667.8000 -220.2100 290.0000 1.9550
-2.4760 2.6850 0 667.8000 -220.2100 290.0000 1.9550
-2.4760 2.6850 0 667.8000 -220.2100 290.0000 1.9550
-4.6580 0.2860 0 626.3700 -220.4200 290.3800 2.0190
-4.6580 0.2860 0 626.3700 -220.4200 290.3800 2.0190
Columns 8 through 10
5.7000 -49.1000 11.1000
5.7000 -49.1000 11.1000
5.7000 -49.1000 11.1000
5.7100 -48.8280 11.1160
5.7100 -48.8280 11.1160
5.7100 -48.8280 11.1160
5.9910 -49.0150 11.1210
5.9910 -49.0150 11.1210
有更好的方法吗?也许有一种方法可以在上面的链接中调整答案,但我没有得到它。
使用答案进行更新
我使用了http://www.mathworks.co.uk/matlabcentral/fileexchange/6436-rude-a-pedestrian-run-length-decoder-encoder处提供的实用程序粗鲁。
mult = data(:,multcol);
data = data(:,1:multcol-1);
iterations = sum(mult);
%preallocate the unwrapped data vector for speed
data_uw = zeros(iterations,multcol-1);
nstep = size(data,1);
ind = 1:nstep;
ind_uw = zeros(iterations,1);
ind_uw = rude(mult,ind);
data_uw = data(ind_uw,:);
这似乎要快得多。 Rude使用了另一个答案中提到的cumsum技术,因此也可以使用。
答案 0 :(得分:2)
该算法是游程解码,我建议使用rude()。这是一个里程碑和编写得非常好的MATLAB代码。
>> rude(N,a)
ans =
1 1 1 2 3 3 3 3 3
在您的情况下,问题应该是预分配(缺少)。预分配和重构代码:
% Pre-allocate
out = zeros(sum(data(:,end)),multcol-1);
for i = 1:size(data,1)
n = data(i,multcol);
out(in : in+n-1,:) = repmat(data(i,1:end-1),n,1);
in = in+n;
end
答案 1 :(得分:0)
简单的事情:
a = [1, 2, 3];
N = [3, 1, 5];
result = zeros(1,sum(N)); % mem alloc
k = 1;
for n = 1:numel(N)
p = k+N(n)-1;
result(1,k:p) = a(n);
k = p+1;
end;
disp(result);
答案 2 :(得分:0)
您可以将基于cumsum的索引用于此类事情:
A = [4 5 6];
N = [3 1 5];
cs=cumsum(N);
idx = zeros(1,cs(end));
idx(1+[0 cs(1:end-1)]) = 1; #%[1 0 0 1 1 0 0 0 0]
idx = cumsum(idx); #%[1 1 1 2 3 3 3 3 3]
B = A(idx); #%[4 4 4 5 6 6 6 6 6]