为什么nansum适用于超出矩阵维度的输入?

Cle*_*leb 3 indexing matlab dimensions multidimensional-array

我想知道matlab的nansum功能.

当我使用文档中的示例时

X = magic(3);
X([1 6:9]) = repmat(NaN, 1, 5);

X =

   NaN     1   NaN
     3     5   NaN
     4   NaN   NaN
Run Code Online (Sandbox Code Playgroud)

然后打电话

>> nansum(X, 1)

ans =

     7     6     0

>> nansum(X, 2)

ans =

     1
     8
     4
Run Code Online (Sandbox Code Playgroud)

它按预期工作.

但是,我没想到的是它也适用于

>> nansum(X, 400)

ans =

     0     1     0
     3     5     0
     4     0     0
Run Code Online (Sandbox Code Playgroud)

这是什么原因?为什么不会因dim超出矩阵尺寸的误差而崩溃?

Wol*_*fie 10

在MATLAB中,所有数组/矩阵都具有无限的单个尾随尺寸.

单身维度是维度dim,在哪里size(A,dim) = 1.当它出现在所有非单例维度之后(即它不会改变矩阵的结构)时,它被称为尾随单例维度.

任何nansum可以在特定维度上操作的函数(包括)都可以在任何一个无限单例维度上执行.通常你不会看到任何影响(例如使用maxsum以这种方式简单地返回输入[1]),但是nansum替换NaN为零,所以这就是发生的一切.

注意与之nansum(A,dim)相同sum(A,dim,'omitnan').您可以通过键入来查看edit nansum.所以我的例子sum用于轻松.有关已定义行为的参考,请参阅本答案的底部.

让我们试着想象一下:

A = ones(3,4);
size( A ) % >> ans = [3, 4]
% Under the hood:
% size( A ) = [3, 4, 1, 1, 1, 1, ...]
sum( A, 1 )   % Sum through the rows, or the 1st dimension, which has 3 elements per sum
              % >> ans = [3 3 3 3]
sum( A, 2 )   % Sum through the columns, or the 2nd dimension, which has 4 elements per sum
              % >> ans = [4; 4; 4]
sum( A, 400 ) % Sum through the ???, the 400th dimension, which has 1 element per sum
              % >> ans = [1 1 1 1; 1 1 1 1; 1 1 1 1]
Run Code Online (Sandbox Code Playgroud)

如果你愿意reshape,原始矩阵可以使用单个第2到第399个维度来进一步:

% Set up dimensions as [3, 1, 1, ..., 1, 1, 4], for a 400-D array!
dims = num2cell( [3 ones(1,398), 4] );
% Note we'll now still have trailing singleton dims, but have 398 in the structure too
B = reshape( A, dims{:} ); 
Run Code Online (Sandbox Code Playgroud)

现在我们可以做一个类似的sum例子.最后要知道的是squeeze删除非尾随单例维度,我们可以用它来整理输出:

sum( B, 1 ); % >> ans(:,:,1,1,1,...,1) = 3 
             % >> ans(:,:,1,1,1,...,2) = 3
             % >> ans(:,:,1,1,1,...,3) = 3
             % >> ans(:,:,1,1,1,...,4) = 3
squeeze( sum( B, 1 ) ); % >> ans = [3; 3; 3; 3] 

% similarly  
squeeze( sum( B, 2 ) );   % >> ans = [1 1 1 1; 1 1 1 1; 1 1 1 1]
squeeze( sum( B, 400 ) ); % >> ans = [4; 4; 4]
Run Code Online (Sandbox Code Playgroud)

我们可以看到,现在我们已经重新塑造了东西,在第400维度上求和与在第二维度中最初求和的情况相同,反之亦然.如果用3替换400,这将更容易可视化!


[ 1 ]请参阅summax文档作为示例,其中行为明确定义"如果dim大于ndims(A)." 在这两种情况下,只需返回即可提高实施效率A.在nansum元素是必须有一些计算的情况下NaN.

  • 谢谢你这个详细的答案; 学到了很多! (2认同)
  • 只是补充一下:原因是因为所有矩阵都是1D内部.尺寸只是在MATLAB中生成索引的更高级别的构造,但在引擎盖下没有ND矩阵,只有1D. (2认同)