2013-05-15 48 views
4

我有一个关于MATLAB中的cellfun函数的问题。何时以及为什么要在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)) 

谢谢!

+1

相关问题: http://stackoverflow.com/questions/16143314/matlab-arrayfun-cellfun-spfun-and-structfun-vs-simple-for-loop – Shai

回答

3

cellfun就像是通过细胞基质和
循环执行指定的函数分别在每个单元。
它通常不是明确
在循环做同样的事情更快,但基本的区别是,它很容易
写入和读取 - 其立即清除呼叫是什么
做。但是你也可以自己写回路。

在特定情况下,你可以使用cellfun这样:

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

如果你有成千上万的细胞,你想要做的事
他们每个人,你要么使用一个循环或cellfun
BTW:@(x)意味着您要将每个单元的内容
理解为x,以便mean(x(:))为您提供什么
您需要 - 整个ma的平均值细胞的trix含量。

4

这当然取决于你想要做什么。 cellfun旨在分别对您的单元格阵列中的每个单元格执行操作。如果你想利用你的数组值的全球平均值,并坚持使用cellfun那么这应该工作:

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

我喜欢使用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()等压缩高维数据数值数据,但你已经提到了这一点。如果数据的大小不统一,这变得更加重要。

2

根据您尝试的解决方案,我想到给出的答案将解决您的问题。但是,在我看来,您的解决方案会比其他解决方案更重视一些价值,并且可能对所有读者都没有价值。
使用您的矩阵,

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

这是的情况下numel(一个{1})〜= numel(一个{2})。

接受的解决方案相当于上述方程的右侧,但原始实现(显然)等于左侧。根据您的需求,这两者都可能是正确的。

保持身体平衡,我提供了一个(许多)方式由每个矩阵重塑一列排列和连接它们来完成你的细胞中的所有元素的非加权平均值:

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

欢迎来到SO!请编辑答案,以便清楚您正在谈论的尝试解决方案/答案。它们显示的顺序并不总是相同的。一旦你将其定位在其他答案之间,读者会想知道你在说什么。 (我无法对你或他人的内容做出任何声明) –

相关问题