Как усреднить массив ячеек из массивов?

У меня есть массив ячеек c из массивов одинакового размера, то есть size(c{n}) = [ m l ... ] для любого n. Как я могу получить значения mean (усреднение по индексу массива ячеек n) для всех элементов массива за один проход? Я думал об использовании cell2mat и mean, но первый не добавляет другого измерения, а меняет l на l*n. И цикл вручную, конечно, занимает вечность ...


person Tobias Kienzler    schedule 04.03.2011    source источник
comment
вопрос расширен до взвешенное усреднение   -  person Tobias Kienzler    schedule 09.03.2011


Ответы (6)


Если все ваши массивы имеют одинаковый размер, имеет смысл хранить их в матрице, а не в массиве ячеек. Это упрощает выполнение операций над ними, например определение среднего значения. Вы можете преобразовать данные в матрицу с помощью функций NDIMS и CAT:

dim = ndims(c{1});          %# Get the number of dimensions for your arrays
M = cat(dim+1,c{:});        %# Convert to a (dim+1)-dimensional matrix
meanArray = mean(M,dim+1);  %# Get the mean across arrays
person gnovice    schedule 04.03.2011
comment
Спасибо, я расширил это сейчас для средневзвешенное значение - person Tobias Kienzler; 09.03.2011

Если у вас более высокая версия Matlab, это можно сделать с помощью функции cellfun. Это может обрабатывать ячейки с неодинаковым размером массива.

C = {1:10, [2; 4; 6], []};
Cmeans = cellfun(@mean, C)
Cmeans =
    5.5000    4.0000       NaN

Ссылка: https://groups.google.com/forum/?fromgroups=#!topic/comp.soft-sys.matlab/S_hyHxy11f0

person Victor Bai    schedule 10.09.2012
comment
Спасибо - я не могу не задаться вопросом, где происходит самое интересное в cellfun: -P Я думаю, это также имеет смысл использовать для моего расширения взвешенного усреднения затем - person Tobias Kienzler; 11.09.2012

Вы на правильном пути. Используйте CELL2MAT, чтобы преобразовать массив ячеек в числовой массив, а затем RESHAPE, чтобы построить трехмерную матрицу. Затем вы можете рассчитать среднее значение, используя функцию MEAN с аргументом измерения:

>> c = {[1 2 3; 4 5 6] [7 8 9; 12 13 14]}

c = 

    [2x3 double]    [2x3 double]

>> mean(reshape(cell2mat(c), [2, 3, 2]), 3)

ans =

     4     5     6
     8     9    10
person b3.    schedule 04.03.2011
comment
+1 или более обычно mean(reshape(cell2mat(c), [ size(c{1}), length(c) ]), ndims(c{1})+1) - person Tobias Kienzler; 07.03.2011
comment
Хотел бы я принять два ответа ... Я выбрал один gnovice, потому что я мог скопировать и вставить его напрямую, но ваше решение работает одинаково хорошо - person Tobias Kienzler; 07.03.2011

Я нашел простой способ найти средние значения в массиве Cell по следующей ссылке: http://www.gomatlab.de/cellfun-t25114.html

Может x быть ячейкой. Потом:

var_mean = cellfun(@mean, x, 'UniformOutput', false); %columnwise mean value


var_mean = cellfun(@(in) mean(in(:)), x); %% mean value of the total "subcell"
person Fried Rice    schedule 06.11.2013
comment
Спасибо! cellfun уже упоминался в этом ответе, но для некоторых может оказаться полезным переключатель UniformOutput. Также: Добро пожаловать в StackOverflow! Найдите минутку, чтобы прочитать сайт about, чтобы узнать, чем этот сайт отличается от обычного форума - вы также получите за это блестящий значок: D - person Tobias Kienzler; 06.11.2013

Это просто проходит по ячейке и означает, что массив опускается до синглтона. Это не займет так много времени, это означает 40 миллионов чисел с плавающей запятой, занимает 1 секунду.

function n = big_mean
tic
c = cell(1000);

for ii = 1:length(c)
    c{ii} = rand(8,7,6,5,4,3,2);
end

n = all_cells(c);
toc
end

function n = all_cells(c)

n = zeros(length(c),1);
for ii = 1:length(c)
    n(ii) = cell_mean(c{ii});
end

n = mean(n);
end

function n = cell_mean(n)

while length(size(n))~=2
    n = mean(n);
end

end

Elapsed time is 1.042459 seconds.

ans =

    0.4999
person Miebster    schedule 04.03.2011
comment
извините, я, возможно, задал свой вопрос слишком расплывчато, я не хочу, чтобы общее среднее значение по всем элементам, но сохраняя базовую структуру массива, получило среднее значение для каждого элемента, см., например, ответ b3 - person Tobias Kienzler; 07.03.2011
comment
но по-прежнему +1 за часть while length - person Tobias Kienzler; 07.03.2011

спасибо за другие комментарии, но иногда бывает сложно переупорядочить данные или изменить способ их сохранения. Для тех из вас, у кого есть эта проблема, вот решение - Enjoy.

a=0;
MyCellAddFun=@(Input) a*eye(size(Input))+Input;
temp=arrayfun(@(ind) MyCellAddFun(CellData{ind}),1:length(CellData),'uniformoutput',false);
answer=temp{end}
person user3330794    schedule 20.02.2014