2016-10-19 3 views
2

각 행에 대해 지정된 열 인덱스에 따라 동작을 수행하여 행렬의 행 수를 줄이고 싶습니다. 다음 예제 데이터 주어 :각 행에 대한 열 인덱스를 기반으로 행렬의 각 행을 효율적으로 축소 할 수 있습니다.

M = magic(4); 
col_ind = [1; 3; 2; 4]; 

제가 첫번째 열은 지정된 열 인덱스까지의 각 행의 로우 합을 포함하도록 3 열로 매트릭스를 확인하고자를 두 번째 열 M 값을 포함 그 행에서 열 인덱스에 의해 지정하고, 마지막 열은 행에있는 엔트리의 나머지의 행의 합을 포함, 즉 매트릭스 M_out 생산 :

M_out = nan(4,3); 
for i = 1:4 
    M_out(i, :) = [sum(M(i, 1:col_ind(i)-1), 2), ... 
     M(i, col_ind(i)), sum(M(i, col_ind(i)+1:end), 2)]; 

end 

되도록 :

>> M_out 

M_out = 

    0 16 18 
    16 10  8 
    9  7 18 
    33  1  0 
+1

체크 아웃'tril','diag','cumsum'와'bsxfun'. –

+0

아 그래, 선형 인덱싱을 사용하여 행 건너편에 cumsum을 사용하는 방법을 알 수있다. – Alex

답변

3

Stewie's comment에 따르면, 여기서는 tril을 사용합니다. 두 번째 열은 sub2ind을 사용하여 간단합니다. cumsum를 사용하여 좀 더 효율적으로,

T = tril(ones(size(M, 2)), -1); 
M_out = zeros(size(M, 1), 3); 
M_out(:, 1) = sum(T(col_ind,:) .* M, 2); 
M_out(:, 2) = M(sub2ind(size(M), (1:size(M, 1)).', col_ind)); 
M_out(:, 3) = sum(M, 2) - sum(M_out, 2); 

을 또는 : : 그런 다음 세 번째 열은 사소하게

cs = cumsum(M, 2); 
M_out = zeros(size(M, 1), 3); 
M_out(:, 2) = M(sub2ind(size(M), (1:size(M, 1)).', col_ind)); 
M_out(:, 1) = cs(sub2ind(size(cs), (1:size(cs, 1)).', col_ind)) - M_out(:, 2); 
M_out(:, 3) = cs(:, end) - sum(M_out, 2); 
+1

니스,하지만'arrayfun'은 양의 옷을 입고있는 늑대입니다 ... 명시 적 루프보다 항상 느립니다 (그러나 더 짧고 쓰기 쉽습니다. 주요 목표). 나는 그것이 OP의 코드를 선호한다고 생각한다. 읽기 쉽도록 섹션으로 나누어 진다면 (M (1, :) = ... M (2, :) = ...;)). 나는'abc'를'M_out (1, :) M_out (2, :) M_out (3, :)'으로 대체 할 것을 제안한다. 그러나 그것은 당신에게 달려있다. –

+0

고맙다. 사실,'arrayfun'은 느리다는 것을 알았다. 하지만 루프보다 느리다는 것을 몰랐습니다 ...! 이제 질문에 대한 귀하의 의견에 따라 코드를 변경하려고합니다! – erfan

+2

'arrayfun'은 많은 오버 헤드가있는 영광스러운'for' 루프입니다. 'arrayfun'에 대해서 내가 가진 유일한 사용법은 셀 배열을 생성 할 수 있다는 것입니다. – rayryeng

관련 문제