Агрегировать 3-е измерение 3D-массива для индексов первого измерения

#matlab #multidimensional-array

#matlab #многомерный-массив

Вопрос:

У меня есть 3-мерный массив размером 4xmx2. (m может быть переменной)

 Val{1} = [1, 280; 2, 281; 3, 282; 4, 283; 5, 285];
Val{2} = [2, 179; 3, 180; 4, 181; 5, 182];
Val{3} = [2, 315; 4, 322; 5, 325];
Val{4} = [1, 95; 3, 97; 4, 99; 5, 101];
  

У меня есть вектор индекса:

 subs = {1,3,4};
  

В качестве выходных данных я хочу получить среднее значение столбца 2 в приведенных выше 2D-массивах (только 1,3 и 4), так что значение 1-го столбца равно>= 2 и <= 4.

Результат будет: {282, 318.5, 98}

Вероятно, это можно сделать с помощью нескольких циклов, но просто интересно, есть ли более эффективный способ?

Ответ №1:

Вот однострочный:

 output = cellfun(@(x)mean(x(:,1)>=2 amp; x(:,1)<=4,2),Val(cat(1,subs{:})),'UniformOutput',false);
  

subs Вместо этого If является числовым массивом (а не массивом ячеек), т. Е. subs=[1,3,4] , и if output не обязательно должен быть массивом ячеек, но может быть числовым массивом, т. Е. output = [282,318.5,98] Тогда вышеуказанное упрощается до

 output = cellfun(@(x)mean(x(x(:,1)>=2 amp; x(:,1)<=4,2)),Val(subs));
  

cellfun применяет функцию к каждому элементу массива ячеек, и индексация гарантирует, что усредняются только правильные строки.

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

1. @ Jonas: Конечно, я это сделаю. Есть еще одна вещь, которую я хотел спросить. Если значение {3} является пустым вектором, код выдает ошибку: ? ?? Попытка доступа к x(:,1); индекс выходит за рамки, поскольку size (x) = [0,0] . Вы знаете, как мы можем избавиться от этой ошибки, напечатать NaN, а не выдавать ошибку

2. @sdhrm: сначала вы можете определить, какие ячейки пусты : emptyCells = cellfun(@isempty,Val); . Затем вы можете поместить [NaN,NaN] в эти ячейки: [Val{emptyCells}] = deal([NaN,NaN]);