最好的量化答案,我可以看到的是:
gridx = arrayfun(@(grix)find((grnum(:)==grix) & (value(:)==grvalue(grix)),1),unique(grnum));
,但我不能說這是一個「快」矢量化的解決方案。 arrayfun
真的很有用,但通常不會比循環更快。
但是,最快的答案並不總是矢量化的。如果我重新實現代碼,你寫它,但有一個更大的數據集:
nValues = 1000000;
value = floor(rand(nValues,1)*100000);
group = num2cell(char(floor(rand(nValues,1)*4)+'a'));
tic;
[grnum, grname] = grp2idx(group);
grvalue = accumarray(grnum,value,[],@max);
toc;
我的電腦給我的0.886秒抽動/ TOC時間。 (注意,所有tic/tock時間來自文件中定義的函數的第二次運行,以避免一次性生成pcode。)
添加「矢量化」(真的是arrayfun
)一行gridx計算導致tic/tock時間爲0.975秒。還不錯,另外一項調查顯示大部分時間都在撥打grp2idx
電話。
如果我們重新實現這個作爲一個非矢量化,簡單的循環,包括gridx
計算,像這樣:
tic
[grnum, grname] = grp2idx(group);
grvalue = -inf*ones(size(grname));
gridx = zeros(size(grname));
for ixValue = 1:length(value)
tmpGrIdx = grnum(ixValue);
if value(ixValue) > grvalue(tmpGrIdx)
grvalue(tmpGrIdx) = value(ixValue);
gridx(tmpGrIdx) = ixValue;
end
end
toc
抽動/ TOC時間約爲0.847秒,稍微比原來的代碼快。
採取這種有點進一步,大部分時間出現在細胞陣列的存儲器訪問丟失。例如:
tic; groupValues = double(cell2mat(group')); toc %Requires 0.754 seconds
tic; dummy = (cell2mat(group')); toc %Requires 0.718 seconds
如果您最初定義組名稱爲數字陣列(例如,我將使用groupValues
正如我上面所定義它們),該時間減少了不少,甚至使用相同的代碼:
groupValues = double(cell2mat(group')); %I'm assuming this is precomputed
tic
[grnum, grname] = grp2idx(groupValues);
grname = num2cell(char(str2double(grname))); %Recapturing your original names
grvalue = -inf*ones(size(grname));
gridx = zeros(size(grname));
for ixValue = 1:length(value)
tmpGrIdx = grnum(ixValue);
if value(ixValue) > grvalue(tmpGrIdx)
grvalue(tmpGrIdx) = value(ixValue);
gridx(tmpGrIdx) = ixValue;
end
end
toc
這產生了0.16秒的tic/tock時間。
你使用哪種matlab版? – Jonas 2013-03-15 21:04:42
@Jonas:2012b,Windows7 x64。 – yuk 2013-03-15 23:19:35