Суммирование разделов массива в matlab

#arrays #matlab #for-loop #sum

#массивы #matlab #для цикла #сумма

Вопрос:

Предположим, у меня есть массив длиной 15

 x = randi([0 5], 1,15);
  

Я хочу суммировать все 3 элемента x вместе и поместить каждую сумму в новый массив с именем y , как показано ниже:

 y = [y1 y2 y3 y4 y5];
  

Пожалуйста, помогите мне сделать это в Matlab, используя циклы for.

Ответ №1:

Вот векторизованный подход, который автоматически обрабатывает возможный меньший последний фрагмент:

 x = randi([0 5], 1, 15); % example data
N = 3; % chunk size
y = accumarray(ceil((1:numel(x))/N).', x(:));
  

Комментарии:

1. Не могли бы вы показать использование циклов for, поскольку это требование

2. @Raykh Я не видел этого требования в вашем вопросе, извините. В любом случае, теперь у вас есть ответы из трех for циклов

Ответ №2:

вы можете использовать reshape следующим образом:

 y = sum(reshape(x,3,[]))
  

Это преобразует ваш вектор x в массив 3 на все, что осталось, затем суммирует по правильному измерению…

В случае, если количество элементов, которые вы хотите суммировать, не соответствует общей длине вектора, вы можете дополнить нулями или NaN в конце, чтобы это сработало. Здесь я выбрал добавление нулей:

 x = randi([0 5], 1,15);
n = 4   ;  % sum every n elements (which is the number of rows in the reshape)
try
    y = sum(reshape(x, n, []));
catch
    disp('added trailing zeros!')
    x(numel(x)   (n - mod(numel(x), n))) = 0;
    y = sum(reshape(x, n, []));
end
  

(вы можете сделать это с условием if вместо этого, мне просто нравится пытаться поймать больше здесь)

Комментарии:

1. не могли бы вы показать мне, как реализовать с помощью циклов for, пожалуйста

2. Использование try / catch здесь довольно плохая практика (и ненужная), вы заранее знаете, с какой проблемой пытаетесь справиться, поэтому обрабатывайте ее, не вызывая ошибок! Разве захваченный случай не обработал бы его независимо, сделав начальный try избыточным?

3. @bla, я использовал функцию reshape, чтобы преобразовать массив в матрицу размером 5X3, затем использовал 2 (вложенных) цикла for для итерации по матрице и суммирования.

4. @Wolfie, я закончил свой ответ, что это можно сделать с условием if… это вопрос предпочтения для этого ответа, мы не отвечаем на более важный вопрос о стиле кода и т.д.

Ответ №3:

Использование for циклов:

 y = zeros(1,5);
for i = 1:5
    idx = (i-1)*3   1:(i-1)*3   3;
    y(i) = sum(x(idx));
end
  

Комментарии:

1. как это возможно? в цикле у вас будет неположительное целое число, а Matlab так не работает.

2. Почему вы так думаете? Если вы ссылаетесь на idx , он всегда возвращает целые числа от 1 до 15 (для данного случая). Вы могли бы переписать это как idx = (i-1)*3 (1:3) , если это поможет вам понять это: на первой итерации, i = 1 так idx = (1-1)*3 (1:3) = 1:3 и так далее.

Ответ №4:

Используя ссылочную переменную Target , которая используется для указания начальной позиции каждого раздела, можно выполнить приведенный ниже цикл. Если вы хотите использовать только циклы, можно выполнить альтернативный внутренний цикл. Этот метод работает почти на том же уровне, что и оконный.

Цикл разделения

Метод 1: одиночный цикл For с индексацией

 x = randi([0 5], 1,15);
y = zeros(1,length(x)/3);


Index = 1;
for Target = 1:  3: 15
    
Partition = x(Target:Target 2); 
y(1,Index) = sum(Partition);
Index = Index   1;
end
  

Метод 2: Внешние и внутренние циклы For

 x = randi([0 5], 1,15);
y = zeros(1,length(x)/3);
Partition = zeros(1,3);

Index = 1;
for Target = 1:  3: 15

for Column = 1:  1: 3
Partition(1,Column) = x(1,Target Column-1); 
end
    
y(1,Index) = sum(Partition);
Index = Index   1;
end