Arrays Matlab:过滤大型数组元素,更快地替代逻辑索引?

Arrays Matlab:过滤大型数组元素,更快地替代逻辑索引?,arrays,matlab,Arrays,Matlab,我有一个大的三维浮动数据集,大约有5亿个元素(3000 x 300 x 600) 我想使元素低于或高于某些阈值零。逻辑索引可以做到这一点,例如 cut_in = 0.5 cut_out = 6 Hs(Hs<cut_in) = 0 ; Hs(Hs>cut_out) = 0 ; cut_in=0.5 切口=6 Hs(Hscut_out)=0; 问题是,这对我来说非常缓慢,因为数据量很大。上面的代码在我的计算机上运行需要240秒。有没有更快的办法 非常感谢,正如@rayryeng和@A

我有一个大的三维浮动数据集,大约有5亿个元素(3000 x 300 x 600)

我想使元素低于或高于某些阈值零。逻辑索引可以做到这一点,例如

cut_in = 0.5
cut_out = 6
Hs(Hs<cut_in) = 0 ;
Hs(Hs>cut_out) = 0 ;
cut_in=0.5
切口=6
Hs(Hscut_out)=0;
问题是,这对我来说非常缓慢,因为数据量很大。上面的代码在我的计算机上运行需要240秒。有没有更快的办法


非常感谢,

正如@rayryeng和@AndrasDeak在对您的问题的评论中指出的那样,逻辑索引通常是最快的,尽管您的运行时表明您可能受到内存(以及被迫交换到磁盘上)的限制,而不是索引的实际速度

在这种情况下,一个令人惊讶的选择是循环。这是因为逻辑索引需要三次通过数组(每个不等式测试一次,更改数据一次),而for循环只需要一次通过数组

基准 因此,我在一台内存为8 GB的机器上运行了这些测试(并意外地将阵列大小增加了一倍):

>> A = randn(6000,300,600);
>> cut_in = -1;
>> cut_out = 1;
使用for循环:

>> tic; for i=1:numel(A), if A(i)<cut_in || A(i)>cut_out, A(i)=0; end; end; toc
Elapsed time is 597.384884 seconds.
#include "mex.h"

void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
    double *A = mxGetPr(prhs[0]);
    size_t N = mxGetNumberOfElements(prhs[0]);
    double cut_in = *mxGetPr(prhs[1]);
    double cut_out = *mxGetPr(prhs[2]);
    // You're not supposed to do in-place operations! Don't do this!
    for (ptrdiff_t ii=0; ii<N; ii++) {
        if ((A[ii]<cut_in) || (A[ii]>cut_out))
            A[ii] = 0;
    }
}

需要记住的一点是,我们在一个机制中运行,访问交换空间是性能的主要瓶颈,因此基准测试结果可能会有所不同,甚至在同一台机器中,这取决于当前主内存中的内容(与需要交换的内容相比)以及正在运行什么样的后台进程。

使用5亿个元素执行此操作。。。这是你能得到的最快的方法<代码>逻辑索引是切片和索引数组的最快方法之一。你必须考虑这个内存占用多少个元素。500000000*8字节/个=4 GB。我也无法重建你的时间安排。我刚刚用随机值在我的电脑上试过,这大约需要2.4秒。您可能还有其他大变量,这些变量会影响可用内存量。请将这两个索引与逻辑
&
放在一起。我认为问题不在于索引:它是对大范围值的内存访问。如果超过一半的数组将被更改,请考虑使用<代码> HSTMP = HS;Hs=零(大小(Hstmp));inds=Hstmp>cut_in&Hstmp代码是最优的,但性能让我惊讶。当我用3000 x 300 x 200运行代码时(我的matlab不可能实现更多),只需3秒钟。我假设你超出了内存,Matlab开始交换数据;抽搐;X(X<0.25)=0;toc表示“有趣”,大约需要20秒。@AndrasDeak:大约275秒,但它使我的系统真的没有响应,所以我不建议对此进行测试。;)但5亿双值中约90%随机分布。。。而不是CPU负载密集型交换:什么版本的MATLAB?什么硬件?R2015b,i7-4610M,16GB,25秒用于循环,9秒用于逻辑索引。@excaza,感谢您提供额外的基准测试;当我在能够将阵列保存在主内存(R2014b、RHEL 6.5、2x E5-2680、256GB)中的机器上运行它时,我会遇到与您类似的情况。然而,原来的海报似乎是在交换是性能瓶颈的情况下运行的,因此这个答案是在更旧的硬件上运行的(R2014b,RHEL 6.5,2x Opteron 248,8GB)。@excaza哈哈,设置不错D@user1877862,不太重要,但您似乎在a=randn(6000300600;
#include "mex.h"

void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
    double *A = mxGetPr(prhs[0]);
    size_t N = mxGetNumberOfElements(prhs[0]);
    double cut_in = *mxGetPr(prhs[1]);
    double cut_out = *mxGetPr(prhs[2]);
    // You're not supposed to do in-place operations! Don't do this!
    for (ptrdiff_t ii=0; ii<N; ii++) {
        if ((A[ii]<cut_in) || (A[ii]>cut_out))
            A[ii] = 0;
    }
}
>> mex -v CXXOPTIMFLAGS="-O3 -DNDEBUG" -largeArrayDims apply_threshold.cpp
>> tic; apply_threshold(A,cut_in,cut_out); toc
Elapsed time is 529.994643 seconds