2013-01-15 79 views
15

我有兩個向量,idx1idx2,我想獲取它們之間的值。如果idx1idx2是數字,而不是載體,我能做到這一點的方式如下:向量化冒號(:)的概念 - MATLAB中兩個向量之間的值

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-loop,但也許Matlab可以更輕鬆地做到這一點。

+0

'values'在MATLAB中是不可能的。由3矢量垂直排列的5矢量? – petrichor

+0

是的,你說得對,對不起。我要糾正這一點。我不介意這些值是否都在同一行,我只需要這些索引之間的所有值。 – Digna

+0

在Mathworks上有一篇關於此主題的優秀博客文章:[矢量化Colon的概念(:)](http://blogs.mathworks.com/loren/2008/10/13/vectorizing-the-notion-冒號) – knedlsepp

回答

11

您的示例輸出不合法。矩陣不能有不同長度的行。你可以做的是使用arrayfun創建一個單元陣列:

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

在得到的單元陣列轉換成向量,就可以使用cell2mat

values = cell2mat(values); 

另外,如果在產生的細胞的所有矢量陣列具有相同的長度,您可以構造一個輸出矩陣,如下所示:

values = vertcat(values{:}); 
+1

謝謝,這有幫助。因爲我只需要這些值,我不介意從哪一行獲得它們,所以我可以使用'horzcat'和'unique',就像這樣:'values = unique(horzcat(values {:}));'I我將閱讀更多關於arrayfun的內容,它似乎非常有用 – Digna

+2

@Digna它看起來很漂亮,但不要濫用它。與for循環相比,它非常緩慢(如果存在「矢量化」解決方案更是如此),所以通常應該選擇後者(除非速度不是問題)......還要注意,您可以編寫' [blah blah]'而不是'horzcat(blah blah)'。 –

0

嘗試進行集合的並集。鑑於idx1價值觀和idx2你提供,運行

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

這將產生一個矢量與價值觀[5 6 7 8 9 10 11],根據需要。

+0

感謝您的回答。問題是'idx1'和'idx2'可能有任何長度(這取決於我正在處理的信號),這種解決方案在這種情況下很難應用,不是嗎? (也許我失去了一些東西:) :) – Digna

+0

啊,哎呀。對不起,我誤解了這個問題。使用'arrayfun'來笛卡爾產品似乎是這裏的一種方式。 – benjwadams

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實際上是colon的默認值,並且可以Uniform代替UniformOutput使用,但我將這些爲求的完整性。

0

Loren有一篇很棒的博客帖子叫Vectorizing the Notion of Colon (:)。它包括比使用arrayfun一個答案是快約5倍(爲大陣列)或for -loop並且類似於運行長度解碼:

的想法是擴大結腸序列進行。我知道每個序列的長度爲 ,所以我知道輸出數組中的起點。填寫 開始值後的值爲1s。然後我計算出多少 從一個序列的末尾跳到下一個序列的開始。 如果有重複的起始值,跳轉可能是負值。一旦 這個數組被填充,輸出就是該序列的累計和或者cumsum。

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);