2015-08-22 90 views
1

我有一個包含位置值三種數值矢量(pos),類別(type)和索引(ind),在這些一般形式計算兩個相鄰的和不相鄰的對之間的差異:使用多個索引向量

pos = 
2 4 5 11 1 5 8 11 12 20 

type = 
1 2 1 2 1 1 2 1 2 3 

ind = 
1 1 1 1 2 2 2 2 2 2 

我想計算在pos內保留的值之間的差異,但只能在相同類型之間,並限於每個索引。使用上面的例子:

當= 1

The difference(s) between type 1 positions = 3 (5-2). 
The difference(s) between type 2 positions = 7 (11-4). 

在任何索引中存在任何給定類型的多於兩個實例的情況下,差異計算順序地從左至右,如圖IND這裏:

當IND = 2

The difference(s) between type 1 positions = 4 (5-1), 6 (11-5). 
The difference(s) between type 2 positions = 4 (12-8). 

儘管索引2包含類型'3',但沒有差別計算,因爲只有此類型的一個實例存在。

類型並不總是隻有1,2或3。

理想情況下,所期望的輸出將是含有相同數量的列作爲length(unique(type))與含有該類型計算的所有差異行矩陣。輸出不需要按索引分開,只有實際的計算需要。在這種情況下有三種獨特的類型,所以輸出將是(添加標籤爲清楚起見只):

Type 1 Type 2 Type 3 
    3  7  0 
    4  4  0 
    6  0  0 

任何空條目可以用零來填充。

有沒有一個簡潔或快速的方式來做到這一點?

EDIT

enter image description here

編輯2:

附加的輸入/輸出實例。

pos = [1 15 89 120 204 209 8 43 190 304] 
type = [1 1 1 2 2 1 2 3 2 3] 
ind = [1 1 1 1 1 1 2 2 2 2] 

希望的輸出:

Type 1 Type 2 Type 3 
    14  84  261 
    74  182  0 
    120  0  0 

在這種情況下,腳本完美地工作:

enter image description here

+2

至少在最近的MATLAB的版本中,我希望用兩個迴路是最快的解決方案。 – Daniel

+2

這種情況下的預期產出是多少?我不明白你想如何把輸出放到一個矩陣中。 – Daniel

+1

檢查OP編輯。 – AnnaSchumann

回答

2

至少對於創建輸出矩陣需要一個循環:

pos = [2 4 5 11 1 5 8 11 12 20] 
type = [1 2 1 2 1 1 2 1 2 3] 
ind = [1 1 1 1 2 2 2 2 2 2] 

%// get unique combinations of type and ind 
[a,~,subs] = unique([type(:) ind(:)] , 'rows') 
%// create differences 
%// output is cell array according to a 
temp = accumarray(subs,1:numel(subs),[],@(x) {abs(diff(pos(x(end:-1:1))))}) 

%// creating output matrix 
for ii = 1:max(a(:,1))    %// iterating over types 
    vals = [temp{ a(:,1) == ii }]; %// differences for each type 
    out(1:numel(vals),ii) = vals; 
end 

out = 

    3  7  0 
    4  4  0 
    6  0  0 

如果它不爲你的真實數據工作,你可能需要unique(...,'rows','stable')'stable' accumarray


看來上述解決方案根據系統給出不同的結果。

的唯一原因,爲什麼代碼可以在不同的機器上給出不同的結果,是accumarray不是「穩定」如上所述。在一些非常罕見的情況下,它可能會返回不可預知的結果。所以,請嘗試以下方法:

pos = [2 4 5 11 1 5 8 11 12 20] 
type = [1 2 1 2 1 1 2 1 2 3] 
ind = [1 1 1 1 2 2 2 2 2 2] 

%// get unique combinations of type and ind 
[a,~,subs] = unique([type(:) ind(:)] , 'rows') 

%// take care of unstable accumarray 
[~, I] = sort(subs); 
pos = pos(I); 
subs = subs(I,:); 

%// create differences 
%// output is cell array according to a 
temp = accumarray(subs,1:numel(subs),[],@(x) {abs(diff(pos(x(end:-1:1))))}) 

%// creating output matrix 
for ii = 1:max(a(:,1))    %// iterating over types 
    vals = [temp{ a(:,1) == ii }]; %// differences for each type 
    out(1:numel(vals),ii) = vals; 
end 

out = 

    3  7  0 
    4  4  0 
    6  0  0