15

我有两个向量idx1idx2,我想获得它们之间的值。如果idx1idx2是数字而不是向量,我可以通过以下方式做到这一点:

idx1=1;
idx2=5;
values=idx1:idx2 

% Result
 % values =
 % 
 %    1     2     3     4     5

但在我的情况下,idx1idx2是可变长度的向量。例如,对于长度 = 2:

idx1=[5,9];
idx2=[9 11];

我可以使用冒号运算符直接获取两者之间的值吗?这是,类似于以下内容:

values = [5     6     7     8     9     9    10    11]

我知道我可以这样做idx1(1):idx2(1)idx1(2):idx2(2)也就是分别提取每列的值,所以如果没有其他解决方案,我可以使用 for 循环来做到这一点,但也许 Matlab 可以更轻松地做到这一点。

4

4 回答 4

11

您的示例输出不合法。矩阵不能有不同长度的行。您可以做的是使用以下方法创建一个元胞数组arrayfun

values = arrayfun(@colon, idx1, idx2, 'Uniform', false)

要将生成的元胞数组转换为向量,您可以使用cell2mat

values = cell2mat(values);

或者,如果生成的元胞数组中的所有向量都具有相同的长度,则可以按如下方式构造输出矩阵:

values = vertcat(values{:});
于 2013-01-15T16:11:37.740 回答
0

尝试取集合的并集。给定idx1idx2你提供的值,运行

values = union(idx1(1):idx1(2), idx2(1):idx2(2));

根据需要,这将产生一个带有值的向量[5 6 7 8 9 10 11]

于 2013-01-15T16:34:17.787 回答
0

我无法让@Eitan 的解决方案起作用,显然您需要为冒号指定参数。接下来的小修改让它在我的 R2010b 版本上运行:

step = 1; 
idx1 = [5, 9];
idx2 = [9, 11];
values = arrayfun(@(x,y)colon(x, step, y), idx1, idx2, 'UniformOutput', false);
values=vertcat(cell2mat(values));

请注意,这step = 1实际上是 中的默认值colonUniform可以用来代替UniformOutput,但为了完整起见,我将它们包括在内。

于 2013-05-27T23:15:39.637 回答
0

Loren有一篇很棒的博文,名为Vectorizing the Notion of Colon (:)。它包含的答案(对于大型数组)比使用arrayfunfor-loop 快 5 倍,并且类似于运行长度解码:

这个想法是扩展冒号序列。我知道每个序列的长度,所以我知道输出数组中的起点。用 1s 填充起始值之后的值。然后我计算出从一个序列的结尾跳到下一个序列的开头的距离。如果有重复的起始值,跳跃可能是负数。一旦这个数组被填充,输出只是序列的累积和或累积和。

function x = coloncatrld(start, stop)
% COLONCAT Concatenate colon expressions
%    X = COLONCAT(START,STOP) returns a vector containing the values
%    [START(1):STOP(1) START(2):STOP(2) START(END):STOP(END)].

% Based on Peter Acklam's code for run length decoding.
len = stop - start + 1;

% keep only sequences whose length is positive
pos = len > 0;
start = start(pos);
stop = stop(pos);
len = len(pos);
if isempty(len)
    x = [];
    return;
end

% expand out the colon expressions
endlocs = cumsum(len);  
incr = ones(1, endlocs(end));  
jumps = start(2:end) - stop(1:end-1);  
incr(endlocs(1:end-1)+1) = jumps;
incr(1) = start(1);
x = cumsum(incr);
于 2015-03-10T23:10:11.643 回答