让accumarray输出一张表

Adr*_*aan 6 arrays matlab accumarray

accumarray 使用两行索引来创建一个矩阵,该矩阵在有效索引对的位置上具有由指定函数指定的值的元素,例如:

A = [11:20]; 
B = flipud([11:20]); 
C = 1:10;
datamatrix = accumarray([A B],C);
Run Code Online (Sandbox Code Playgroud)

这种方式datamatrix将是一个20x20带有值的矩阵.如果值A以及B但是都非常大,这将导致大部分是空的矩阵,在远角小批量的数据.为了避免这种情况,可以设置accumarrayissparse:

sparsedatamatrix = accumarray([A B],C,[],@sum,[],true);
Run Code Online (Sandbox Code Playgroud)

这将节省大量内存min(A)和/或min(B)非常大.

然而,我的问题是我有一个Mx7矩阵,M~1e8我希望根据前两列中的索引收集第三列到第七列的方法,以及基于第三列的第三列的标准偏差:

result = accumarray([data(:,1) data(:,2)],data(:,3),[],@std);
Run Code Online (Sandbox Code Playgroud)

我想保存此回一个表,构成为[X Y Z std R G B I],在这里XY是指数,Z是该像素的平均高度,R,G,BI是每个象素的平均值(颜色和强度)和std是高度的标准偏差(即粗糙度).使用issparse在这种情况下没有帮助,因为我改变我的矩阵日起,accumarray使用repmat.

该代码的要点是从点云估计一块土地的高度,粗糙度,颜色和强度.我舍入了X和Y中的坐标来创建一个网格,现在需要每个网格单元的平均值,但输出为"表"(不是MATLAB数据类型,而是一个不是默认矩阵输出的2D数组).

那么,总结一下这个问题:

有没有办法accumarray或类似的功能输出这个表没有中间(可能非常大)的矩阵?

代码如下:

Xmax = max(Originaldata(:,1));
Ymax = max(Originaldata(:,2));
X_avg_grid=(Edgelength:Edgelength:Xmax*Edgelength)+Xorig;
TestSet = zeros(Xmax*Ymax,9);

xx = [1:length(X_avg_grid)]'; %#ok<*NBRAK>
TestSet(:,1) = repmat(xx,Ymax,1);
ll = 0:Xmax:Xmax*Ymax;
for jj = 1:Ymax
    TestSet(ll(jj)+1:ll(jj+1),2) = jj;
end

for ll = 1:7
    if ll == 2
        tempdat = accumarray([Originaldata(:,1) Originaldata(:,2)],Originaldata(:,3),[],@std);
        tempdat = reshape(tempdat,[],1);
        TestSet(:,ll+2) = tempdat;
    elseif ll == 7
        tempdat = accumarray([Originaldata(:,1) Originaldata(:,2)],1);
        tempdat = reshape(tempdat,[],1);
        TestSet(:,ll+2) = tempdat;
    elseif ll == 1
        tempdat = accumarray([Originaldata(:,1) Originaldata(:,2)],Originaldata(:,3),[],@mean);
        tempdat = reshape(tempdat,[],1);
        TestSet(:,ll+2) = tempdat;
    else
        tempdat = accumarray([Originaldata(:,1) Originaldata(:,2)],Originaldata(:,ll+1),[],@mean);
        tempdat = reshape(tempdat,[],1);
        TestSet(:,ll+2) = tempdat;
    end
end

TestSet = TestSet(~(TestSet(:,9)==0),:);
Run Code Online (Sandbox Code Playgroud)

这里的第九列只是每个单元格的点数.

Originaldata = 
19  36  2.20500360107422    31488   31488   31488   31611
20  37  2.26400360107422    33792   33792   34304   33924
20  37  2.20000360107422    33536   33536   34048   33667
19  36  2.20500360107422    34560   34560   34560   34695
20  36  2.23300360107422    32512   32512   33024   32639
21  38  2.22000360107422    31744   31488   33024   31611
21  37  2.20400360107422    32512   32768   33792   32896
21  37  2.24800360107422    29696   29440   30720   29555
21  38  2.34800360107422    32768   32768   32768   32639
21  37  2.23000360107422    33024   33024   33536   33153
Run Code Online (Sandbox Code Playgroud)

因此,相同的X,Y(例如[19 36][21 37])上的所有点被平均(高度,RGB,按此顺序的强度)以及第三列中的值也需要标准偏差:

Result = 
19  36  2.2050036   0.00        33024   33024   33024       33153
21  37  2.227336934 0.02212088  31744   31744   32682.66    31868
Run Code Online (Sandbox Code Playgroud)

等等其余数据.

我将我的代码更新为我的最新版本.这大大减少了内存开销,因为该函数现在一个接一个地创建网格而不是一次创建网格.但是,代码并行运行,因此仍然创建了八个同时网格,因此仍然可以理解解决方案.

Sha*_*hai 3

使用线性索引和二维稀疏矩阵的解决方案草图

lind = Originaldata(:,1) + max( Originaldata(:,1) ) * ( Originaldata(:,2) - 1 );
daccum(7,:) = accumarray( lind, 1, [], @sum, [], true ); %// start with last one to pre-allocate all daccum
daccum(1,:) = accumarray( lind, Originaldata(:,3), [], @mean, [], true );
daccum(2,:) = accumarray( lind, Originaldata(:,3), [], @std, [], true );
daccum(3,:) = accumarray( lind, Originaldata(:,4), [], @mean, [], true );
daccum(4,:) = accumarray( lind, Originaldata(:,5), [], @mean, [], true );
daccum(5,:) = accumarray( lind, Originaldata(:,6), [], @mean, [], true );
daccum(6,:) = accumarray( lind, Originaldata(:,7), [], @mean, [], true );
Run Code Online (Sandbox Code Playgroud)

现在您只能获得您需要的东西

inter = [Originaldata(:,1), Originaldata(:,2), full( daccum(:,lind) )' ];
Run Code Online (Sandbox Code Playgroud)