【问题标题】:Efficient way to reshape (alternately) thousands of data重塑(交替)数千个数据的有效方法
【发布时间】:2017-03-22 05:40:49
【问题描述】:

我有一个非常大的数据集,有数千行和数百列。我尝试交替重塑每第 n 行的数据和所有第 n 行列数据。我试过这样:

in=rand(71760,320);
m=240; n=320;
[R,C]=size(in); 
out=[];
R_out=R/m; 

for k=1:m %from row 1 to mth row
    for i=1:C %reshape every column of mth row
        out=[out;reshape(in(k:m:end,i),R_out,1)'];
    end
end

如果您尝试代码,它会花费很长时间并且根本没有效率,您甚至都不会费心让它完成。如何提高性能?还是有更好的方法?

更新

这个问题被扩展到另一个线程here,以提高@Teddy提供的reshape answer的性能

【问题讨论】:

  • 你的意思是 for k=1:m 而不是 for k=1:n 吗?因为你在行中跨步m(而n 是列)。您能否澄清out 的预期大小?
  • 对不起我的错误。已编辑。预期的输出大小将是 (m x C, R/m),对于上述情况,它将是 (76800, 299)

标签: matlab reshape


【解决方案1】:

需要这么长时间的原因是out矩阵应该是preallocated

例如,这在我的笔记本电脑上大约 1 秒内完成:

in=rand(71760,320);
m=240; n=320;
[R,C]=size(in); 
R_out=R/m; 

out=zeros(m*C,R_out);
for k=1:m %from row 1 to nth row
    for i=1:C %reshape every column of nth row
        out(i+C*(k-1),:) = in(k:m:end,i)';
    end
end

替代方法

最佳做法是使用arrayfun 的矢量化方法,这可以像这样在一行中完成:

out=cell2mat(arrayfun(@(k) in(k:m:end,:)', 1:m,'uniformoutput',0)');

这也运行得更快。

【讨论】:

  • 与我的原始代码相比,它确实需要几秒钟才能完成。感谢您的帮助!
  • 虽然单线在美学上更好,但它很少会更快,除非当然使用 GPU。参见例如stackoverflow.com/questions/12522888/…
  • 我所指的矢量化是针对分配的,与原始循环分配相比,它显着提高了性能。但是,我同意如果将 arrayfun 调用替换为内部带有矢量化赋值的循环会更快。
  • 测试了矢量化方法,它确实显着提高了性能。但是,如果数据变大,循环和矢量化方法都无法处理。我在这里说的大小类似于:in=rand(291081,1920); 其中m=581;。有什么建议来处理这类问题吗?如果可能的话,不涉及 GPU。谢谢!
  • @JDane 正如 Nicky 上面提到的那样,您可以通过使用第二种方法的矢量化分配,使用显式 for 循环而不是 arrayfun/cell2mat 对这两种方法进行轻微改进,因为这些方法会带来很小的开销。但是,这不会有很大的不同。此外,由于这是与原始问题(预分配)不同的问题,您可能希望发布一个新问题,专门询问改进此答案中方法的方法。也许有人会知道更快的方法。如果您这样做,请在此处添加一个链接。
猜你喜欢
  • 2020-07-31
  • 2020-01-23
  • 1970-01-01
  • 2017-09-09
  • 2021-08-30
  • 2019-11-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多