首页 文章

matlab中沿nd数组维度的平均值

提问于
浏览
1

例如,在matlab中计算沿着nd数组维度的每个二进制位的平均值,沿着4d数组的dim 4平均每10个元素

x = reshape(1:30*30*20*300,30,30,20,300);    
n = 10; 
m = size(x,4)/10;
y = nan(30,30,20,m);
for ii = 1 : m
    y(:,:,:,ii) = mean(x(:,:,:,(1:n)+(ii-1)*n),4);
end

看起来有点傻 . 我认为必须有更好的方法来平均垃圾箱?

此外,是否可以使脚本适用于一般情况,即,对数组进行仲裁,并沿着仲裁调整平均值?

2 回答

  • 1

    对于问题的第二部分,您可以使用:

    x = reshape(1:30*30*20*300,30,30,20,300);    
    dim = 4;
    n = 10; 
    m = size(x,dim)/10;
    y = nan(30,30,20,m);
    idx1 = repmat({':'},1,ndims(x));
    idx2 = repmat({':'},1,ndims(x));
    for ii = 1 : m
        idx1{dim} = ii;
        idx2{dim} = (1:n)+(ii-1)*n;
        y(idx1{:}) = mean(x(idx2{:}),dim);
    end
    

    对于问题的第一部分,这里是使用 cumsumdiff 的替代方法,但它可能不比循环解决方案更好:

    function y = slicedmean(x,slice_size,dim)
        s = cumsum(x,dim);
        idx1 = repmat({':'},1,ndims(x));
        idx2 = repmat({':'},1,ndims(x));
        idx1{dim} = slice_size;
        idx2{dim} = slice_size:slice_size:size(x,dim);
        y = cat(dim,s(idx1{:}),diff(s(idx2{:}),[],dim))/slice_size;
    end
    
  • 1

    这是一个使用 accumarray 函数的通用解决方案 . 我没有测试它有多快 . 可能还有一些改进的余地 .

    基本上,accumarray将x中的值按照您的问题的自定义索引矩阵进行分组

    x = reshape(1:30*30*20*300,30,30,20,300); 
    s = size(x);
    
    % parameters for averaging
    dimAv = 4; 
    n = 10;
    
    % get linear index
    ix = (1:numel(x))';
    
    % transform them to a matrix of index per dimension
    % this is a customized version of ind2sub
    pcum = [1 cumprod(s(1:end-1))];
    sub = zeros(numel(ix),numel(s));
    for i = numel(s):-1:1,
        ixtmp = rem(ix-1, pcum(i)) + 1;
        sub(:,i) = (ix - ixtmp)/pcum(i) + 1;
        ix = ixtmp;
    end
    
    % correct index for the given dimension
    sub(:,dimAv) = floor((sub(:,dimAv)-1)/n)+1;
    
    % run the accumarray to compute the average
    sout = s;
    sout(dimAv) = ceil(sout(dimAv)/n);
    y = accumarray(sub,x(:), sout, @mean);
    

    如果您需要更快,更高效的内存操作,则必须编写自己的mex函数 . 我想,这应该不会那么困难!

相关问题