我们假设我有以下9 x 5矩阵:
myArray = [
54.7 8.1 81.7 55.0 22.5
29.6 92.9 79.4 62.2 17.0
74.4 77.5 64.4 58.7 22.7
18.8 48.6 37.8 20.7 43.5
68.6 43.5 81.1 30.1 31.1
18.3 44.6 53.2 47.0 92.3
36.8 30.6 35.0 23.0 43.0
62.5 50.8 93.9 84.4 18.4
78.0 51.0 87.5 19.4 90.4
];
我有11个这个矩阵的“子集”,我需要在每个子集上运行一个函数(比如说max).可以使用以下逻辑逻辑来识别子集(按列标识,而不是按行标识):
myLogicals = logical([
0 1 0 1 1
1 1 0 1 1
1 1 0 0 0
0 1 0 1 1
1 0 1 1 1
1 1 1 1 0
0 1 1 0 1
1 1 0 0 1
1 1 0 0 1
]);
或通过线性索引:
starts = [2 5 8 10 15 23 28 31 37 40 43]; #%index start of each subset
ends = [3 6 9 13 18 25 29 33 38 41 45]; #%index end of each subset
这样第一个子集是2:3,第二个子集是5:6,依此类推.
我可以找到每个子集的最大值并将其存储在向量中,如下所示:
finalAnswers = NaN(11,1);
for n=1:length(starts) #%i.e. 1 through the number of subsets
finalAnswers(n) = max(myArray(starts(n):ends(n)));
end
循环运行后,finalAnswers包含每个数据子集的最大值:
74.4 68.6 78.0 92.9 51.0 81.1 62.2 47.0 22.5 43.5 90.4
是否可以在不使用for循环的情况下获得相同的结果?换句话说,这个代码可以被矢量化吗?这种方法会比现在更有效吗?
编辑:
我对提出的解决方案做了一些测试.我使用的数据是1,510 x 2,185矩阵,其中10,103个子集的长度从2到916不等,子集长度的标准偏差为101.92.
我将每个解决方案包装在tic中;对于k = 1:1000 [code here] end; TOC;以下是结果:
> for loop方法—经过的时间是16.237400秒.
> Shai的方法—经过的时间是153.707076秒.
> Dan的方法—经过的时间是44.774121秒.
> Divakar的方法#2 —经过的时间是127.621515秒.
笔记:
>我还尝试通过将k = 1:1000包裹在仅仅精确线的周围来对Dan的方法进行基准测试(因为剩下的可能是
理论上只运行一次).在这种情况下,时间是28.29
秒.
>对Shai的方法进行基准测试,同时保留lb = …线
在k循环中,时间为113.48秒.
>当我运行Divakar的代码时,我获得了两个非单例维度
输入数组必须相互匹配. bsxfun行的错误.
我通过使用共轭转置(撇号)来“固定”这个
trade_starts上的operator’)(1:starts_extent)和
调用bsxfun的代码行中的intv(1:starts_extent).我
不确定为什么会出现这个错误……
我不确定我的基准测试设置是否正确,但似乎for循环实际上在这种情况下运行最快.