gpt4 book ai didi

matlab - 使用一组开始和结束索引索引数组

转载 作者:行者123 更新时间:2023-12-03 17:05:54 25 4
gpt4 key购买 nike

我有两个数组:

timesteps = [1,3;5,7;9,10];
data = [1,2,3,4,5,6,7,8,9,10];

timesteps 数组中的值描述了我想要的data 值。第一列开始,第二列结束。

例如在这里我想得到 [1,2,3,5,6,7,9,10]

所以这段代码对我来说工作得很好,但是由于 for 循环它非常慢...Matlab 中是否有一个单行代码以便我可以摆脱 for 循环?

newData=[];
for ind=1:size(timesteps,1)
newData=cat(2,newData,data(timesteps(ind,1):timesteps(ind,2)));
end



编辑:使用来自 Wolfie 的解决方案我得到了以下(非常好的)结果。 (我只使用了一个小数据集,通常是它的 50 倍大。)

(Mine)    Elapsed time is 48.579997 seconds.
(Wolfies) Elapsed time is 0.058733 seconds.

最佳答案

Irreducible's answer使用 str2numsprintf 在数字和字符数据之间切换以创建索引......这比你已经完成的循环性能低(在我的测试中)对于小型阵列,但对于大型阵列更快,因为内存分配得到了更好的处理。

您可以通过预分配输出并对其进行索引以避免循环中的串联来提高性能。对于大型阵列,这可以大大加快速度。

N = [0; cumsum( diff( timesteps, [], 2 ) + 1 )];
newData = NaN( 1, max(N) );
for ind = 1:size(timesteps,1)
newData(N(ind)+1:N(ind+1)) = data(timesteps(ind,1):timesteps(ind,2));
end

下面的基准显示了这是如何持续更快的。

  • x轴:data中的元素个数
  • y 轴:以秒为单位的时间
  • 假设:选择索引的随机子集,其中 index 的行数比 data 少 4 倍。

基准图

benchmark

请注意,这是可变的,具体取决于所使用的索引。在下面的代码中,我在每次运行时随机生成索引,因此您可能会看到绘图有点跳跃。

但是,具有预分配的循环始终更快,而没有预分配的循环始终呈指数增长。


基准代码

T = [];
p = 4:12;
for ii = p
n = 2^ii;
k = 2^(ii-2);

timesteps = reshape( sort( randperm( n, k*2 ) ).', 2, [] ).';
data = 1:n;

f_Playergod = @() f1(timesteps, data);
f_Irreducible = @() f2(timesteps, data);
f_Wolfie = @() f3(timesteps, data);

T = [T; [timeit( f_Playergod ), timeit( f_Irreducible ), timeit( f_Wolfie )]];
end

figure(1); clf;
plot( T, 'LineWidth', 1.5 );
legend( {'Loop, no preallocation', 'str2num indexing', 'loop, with preallocation'}, 'location', 'best' );
xticklabels( 2.^p ); grid on;

function newData = f1( timesteps, data )
newData=[];
for ind=1:size(timesteps,1)
newData=cat(2,newData,data(timesteps(ind,1):timesteps(ind,2)));
end
end
function newData = f2( timesteps, data )
newData = data( str2num(sprintf('%d:%d ',timesteps')) );
end
function newData = f3( timesteps, data )
N = [0; cumsum( diff( timesteps, [], 2 ) + 1 )];
newData = NaN( 1, max(N) );
for ind = 1:size(timesteps,1)
newData(N(ind)+1:N(ind+1)) = data(timesteps(ind,1):timesteps(ind,2));
end
end

关于matlab - 使用一组开始和结束索引索引数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57787803/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com