5

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

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

一个简单的例子:假设我有一个单元格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

4 回答 4

4

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

mean_a = mean(cell2mat(cellfun(@mean, a,'UniformOutput',0)))
于 2013-05-15T20:21:01.890 回答
4

cellfun就像循环遍历单元矩阵并
在每个单元上分别执行指定的函数一样。
它通常比
在循环中显式地做同样的事情要快,但基本的区别在于它易于
编写和阅读——它立即清楚调用在
做什么。但是您也可以自己编写循环。

在您的特定情况下,您可以使用cellfun这种方式:

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

如果您有数千个单元格,并且您想对
每个单元格执行某些操作,则可以使用循环或cellfun
顺便说一句:@(x)意味着您希望每个单元格的内容
被理解为x这样可以mean(x(:))为您提供所需的内容
-整体的意思单元格的矩阵内容。

于 2013-05-16T00:56:07.973 回答
3

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

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

这是 numel(a{1}) ~= numel(a{2}) 的情况。

接受的解决方案等价于上述等式的右侧,但原始实现(显然)等于左侧。考虑到您的需要,任何一个都可能是正确的。

为了平衡,我提供了一种(多种)方法来完成单元格所有元素的非加权平均值,方法是将每个矩阵重塑为列数组并将它们连接起来:

b = cellfun(@(x) reshape(x, 1, []), a, 'UniformOutput', false);
mean_a = mean([b{:}])
于 2016-07-11T20:50:44.827 回答
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() 等压缩高维数据数值数据,但您已经提到过这一点。如果数据大小不统一,这一点就变得更加重要。

于 2016-07-06T10:12:38.857 回答