使用来自另一个向量的位置处的另一个向量的值填充向量的所有值

时间:2013-08-19 15:54:24

标签: matlab

我有两个向量来表示边缘并对一些连续数据进行调整(此时此模拟)。

edges = [50, 120, 170, 200, 220, 224, 250]
levels = [24,3,30,0,36,0]

如何创建一个矢量,前50个条目有24个,后续120个等等3个?

我试过

psd = zeros(1,250)
psd(edges) = levels

但这只是将一个值放在相关位置 - 这不是我想要的。

5 个答案:

答案 0 :(得分:1)

您的说明和代码不完全匹配。你想psd有250个元素或1234(sum(edges),因为你后续使用意味着什么)?如果是后者,您只需修改edges = cumsum(edges)即可。其次,你没有足够的水平用于给定的边缘。

这是一个不使用循环的解决方案。

edges = [50, 120, 170, 200, 220, 224, 250];
levels = [24,3,30,0,36,0,nan]; % padded with nan for equal length
idxs = length(levels) - sum(bsxfun(@(x,y) x < y,1:max(edges),edges'+1))+1;
pds = levels(idxs)

甚至更简单:

idxs = zeros(1,max(edges));
idxs(edges(1:end-1)+1) = 1;
psd = levels(cumsum(idxs)+1)

答案 1 :(得分:1)

如果edges确实是您的间隔的边缘,这是一个小解决方案:

使用0作为第一个元素展开向量levels

levels = [0, 24, 3, 30, 0, 36, 0];

然后您可以执行以下操作:

psd = zeros(1,250);
psd(edges(2:end)-1) = diff(levels);
psd = cumsum(psd);

您在间隔限制处将两个连续值的偏移量设置为0,其他地方为0。总结时,你有你所期望的。

答案 2 :(得分:0)

涉及循环,但应该没问题。此外,您的edgeslevels需要具有相同的长度。

v = [];
for i = 1:numel(edges)
    v = [v;level(i)*ones(edges(i),1)];
end

这是一个更有效的版本,负责分配开销。

v = zeros(sum(edges),1);
c = [0 cumsum(edges)];
for i = 1:numel(edges)-1
    v( c(i)+1:c(i+1) ) = levels(i)*ones(edges(i),1);
end

记住;在今天的MATLAB中,循环并不总是邪恶的。有时,这是最简单(也是最清晰)的解决方案。

答案 3 :(得分:0)

您可以使用此运行长度解码实用程序FEX rude(),它实现了Bentoy13显示的方法:

% example inputs
edges  = [2, 3, 1];
levels = [24,3,30];

结果

rude(edges, levels)
ans =
    24    24     3     3     3    30

答案 4 :(得分:0)

受到an answer gnovice的启发,您可以使用此功能:

psd = levels(cumsum(sparse(1,cumsum([1 edges(1:end-1)]),1,1,sum(edges))));

为了方便起见,您可以创建一个匿名函数并重新使用它:

populate = @(L,E) L(cumsum(sparse(1,cumsum([1 E(1:end-1)]),1,1,sum(E))));
psd = popultae(levels, edges);