2013-05-15 45 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!請編輯答案,以便清楚您正在談論的嘗試解決方案/答案。它們顯示的順序並不總是相同的。一旦你將其定位在其他答案之間,讀者會想知道你在說什麼。 (我無法對你或他人的內容做出任何聲明) –

相關問題