2014-01-21 5 views

ответ

2

В случае, если вы достичь ситуации, когда третье измерение не делится на 24, то вы можете сделать это:

n = 24; 
subs = ceil((1:size(A,3))/n) 

for ii = 1:size(A, 1) 
    for jj = 1:size(A,2) 

     result(ii,jj,:) = accumarray(subs', squeeze(A(ii,jj,:))); 

    end 
end 
5

reshape в 4-й размерности, sum в 3-м и squeeze:

B = squeeze(sum(reshape(A, size(A,1),size(A,2),24,[]), 3)); 
+2

или: 'изменения формы (А, размер (А, 1), размер (А, 2), [], 24) 'для автоматического определения f третьего измерения. – Jonas

+1

также я бы использовал 'permute (.., [1 2 4 3])' вместо 'squeeze', чтобы избавиться от размерности синглтона (более явное определение IMO) – Amro

+0

Кстати, это должно быть' reshape (A, size (A, 1), размер (A, 2), 24, []) '(и тот же флип для версии Роди) – Amro

4

для чего это стоит, вот для цикла версии:

A = rand(70,51,8760); % sample data 3D matrix 
n = 24;    % group every n-pages and sum across the 3rd dimension 

% calculate starting indices 
sz = size(A); 
ind = 1:n:sz(3); 

% compute the sums in each group of pages 
B = zeros(sz(1),sz(2),numel(ind)); 
for k=1:numel(ind) 
    B(:,:,k) = sum(A(:,:,ind(k):ind(k)+n-1), 3); 
end 

Вышеупомянутое предполагает, что size(A,3) равномерно делится на n. Конечно, его можно было бы отрегулировать, если это не так, обработав первые fix(size(A,3)/n)*n фрагменты, как и раньше, затем выполнив оставшиеся страницы, используя последнюю итерацию.


Вы могли бы сравнить приведенный выше код против @RodyOldenhuis's solution:

B2 = permute(sum(reshape(A,sz(1),sz(2),n,[]),3), [1 2 4 3]); 
assert(isequal(B,B2)) 

(В моих тестах, это было быстрее, чем для цикла, но не намного)


Мне также удалось полностью векторизовать @Dan's solution в одном accumarray звонок:

[I,J,K] = ndgrid(1:sz(1),1:sz(2),1:sz(3)); 
B3 = accumarray([I(:) J(:) ceil(K(:)./n)], A(:)); 
assert(isequal(B,B3)) 

(Внимание: эта версия памяти интенсивно, не говоря уже о гораздо медленнее, чем другие решения)

Смежные вопросы