我何时以及为什么要在Matlab中使用cellfun?

时间:2013-05-15 19:52:16

标签: matlab cell

我对MATLAB中的cellfun函数有疑问。

何时/为什么要使用它,何时我也可以放弃它?

一个简单的例子:假设我有一个单元格a,我想找到a中所有值的平均值。

a{1} = [1 2;3 4];
a{2} = [1 2 3;4 5 6; 7 8 9];

我的方法是:

mean([a{1}(:); a{2}(:)])

适当的cellfun版本将会是什么,并且它会更好吗?

我尝试过做这样的事情(显然不行):

mean_a = mean(cellfun(@mean, a,'UniformOutput',0))

谢谢!

4 个答案:

答案 0 :(得分:4)

这当然取决于你想做什么。 cellfun旨在单独对单元格数组中的每个单元格执行操作。如果您想获取单元格数组值的全局均值,并坚持使用cellfun,那么这应该有效:

mean_a = mean(cell2mat(cellfun(@mean, a,'UniformOutput',0)))

答案 1 :(得分:3)

cellfun就像循环遍历单元格矩阵一样 在每个单元格上单独执行指定的功能 它通常比明确地做同样的事情更快 在循环中,但基本的区别在于它易于实现 写和读 - 它立即清楚通话是什么 这样做。但你也可以自己编写循环。

在您的具体情况下,您可以这样使用cellfun

mean_a = mean(cellfun(@(x) mean(x(:)), a));

如果你有成千上万的细胞,你想做点什么 对于他们每个人你要么使用循环或cellfun
BTW:@(x)表示您想要每个单元格的内容 被理解为x,以便mean(x(:))给你什么 你想要的 - 细胞的整个矩阵内容的平均值。

答案 2 :(得分:3)

Based on your attempted solution, I imagine that the answers given will solve your problem. However, it appears to me your solution will weight some values more than others and may not be valuable to all readers.
Using your matrices,

mean([a{1}(:); a{2}(:)]) ~= mean([mean(a{1}(:)) mean(a{2}(:))])
                  4.2308 ~= 3.75

This is the case where numel(a{1}) ~= numel(a{2}).

The accepted solution is equivalent to the right side of the above equation, but the original implementation is (obviously) equal to the left side. Either could be correct given your needs.

For balance, I offer one (of many) ways to accomplish a non-weighted mean of all the elements of your cell by reshaping each matrix to a column array and concatenating them:

b = cellfun(@(x) reshape(x, 1, []), a, 'UniformOutput', false);
mean_a = mean([b{:}])

答案 3 :(得分:1)

我喜欢使用cellfun绘制操作而不是循环,例如,如果我有多组传感器数据并且每组有多列(因为每组有多个传感器),使用

非常方便
numOfSensors = 5;
numOfSets = 6;

%% sample data preparation
x = 1:100;
y = rand(length(x), numOfSets*numOfSensors);
yCell = mat2cell(y, 100, numOfSensors*ones(1,numOfSets)); % this is my sensor data
scaleCell = num2cell(fliplr(cumsum(1:numOfSets)));
yCell = cellfun(@(x, scale)x.*scale, yCell, scaleCell, 'unif', false);

%% plot preparation
nameCell = arrayfun(@(x)['sensor set ' num2str(x)], 1:numOfSets, 'unif', false);
colorCell = num2cell(lines(numOfSets), 2)';

%% plot
figure, hold all,
set(gca, 'ColorOrder', [0 0 0], 'LineStyleOrder', {'-','--','-*','-.',':'})
h = cellfun(@(y, name, c)plot(x, y, 'linewidth', 1.5, 'displayName', name, 'color', c), yCell, nameCell, colorCell, 'unif', false);
hh = cellfun(@(x)x(1), h, 'unif', false);
legend([hh{:}])

而不是循环。此示例绘制所有数据集,每个数据集都有自己的颜色,每个数据集的每个传感器都有其他线型。仅为每个数据集显示图例(注意:这也可以通过使用hggroups来完成)。

或者更简单的用例 - 我再次拥有一个数据单元格数组,并希望在其中有一个简短的视图:

figure, hold all, cellfun(@plot,dataCell)

就是这一行,在命令行中非常快。

另一个很好的用例是使用mean(),max(),min(),std()等来压缩高维数据数据,但是你已经提到了这一点。如果数据的大小不均匀,这就变得更加重要。