我对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))
谢谢!
cellfun
就像循环细胞矩阵一样
在每个单元上分别执行指定的功能。
它通常比明确地做同样的事情更快
在循环中,但基本的区别在于它易于使用
写和读 - 它立即清楚通话是什么
这样做。但你也可以自己编写循环。
在您的具体情况下,您可以这样使用cellfun
:
mean_a = mean(cellfun(@(x) mean(x(:)), a));
如果你有成千上万的细胞,你想做点什么
对于他们每个人你要么使用循环或cellfun
顺便说一句:@(x)
意味着你想要每个细胞的内容
被理解为x
,以便mean(x(:))
给你什么
你想要的 - 细胞的整个矩阵内容的平均值。
它当然取决于你想做什么。 cellfun
旨在单独对您的细胞阵列中的每个细胞起作用。如果你想获取你的单元格数组值的全局平均值,并坚持使用cellfun
那么这应该工作:
mean_a = mean(cell2mat(cellfun(@mean, a,'UniformOutput',0)))
根据您尝试的解决方案,我认为给出的答案将解决您的问题。但是,在我看来,你的解决方案会比其他人更重视某些价值观,并且可能对所有读者都没有价值。 使用你的矩阵,
mean([a{1}(:); a{2}(:)]) ~= mean([mean(a{1}(:)) mean(a{2}(:))])
4.2308 ~= 3.75
这是numl(a {1})〜= numel(a {2})的情况。
接受的解决方案等同于上述等式的右侧,但原始实现(显然)等于左侧。根据您的需要,两者都可能是正确的。
为了平衡,我提供了一种(多种)方法来通过将每个矩阵重新整形为列数组并连接它们来完成单元格中所有元素的非加权平均值:
b = cellfun(@(x) reshape(x, 1, []), a, 'UniformOutput', false);
mean_a = mean([b{:}])
我喜欢使用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()等压缩高维数据数据,但是你已经提到了这一点。如果数据的大小不均匀,这就变得更加重要。