2008-10-19 256 views
8

我想用MATLAB將函數應用於矩陣中的所有列。例如,我希望能夠在矩陣的每一列調用平滑,而不是平滑地將矩陣視爲向量(如果調用smooth(矩陣),則這是默認行爲)。在MATLAB中迭代矩陣列的最佳方式是什麼?

我敢肯定,必須有這樣做的更地道的方式,但我不能找到它,所以我定義的map_column功能:

function result= map_column(m, func) 
    result= m; 
    for col= 1:size(m,2) 
     result(:,col)= func(m(:,col)); 
    end 
end 

,我可以打電話:

smoothed= map_column(input, @(c) (smooth(c, 9))); 

有什麼不對的代碼?我怎麼能改進它?

回答

3

您的解決方案很好。

請注意,對於大型矩陣,horizcat會造成實質性的損失。它使代碼爲O(N^2)而不是O(N)。對於一個100x10,000的矩陣,我的機器上的實現需要2.6s,horizcat需要64.5s。對於100x5000矩陣,horizcat實現需要15.7s。

如果你願意,你可以概括你的函數一點,使之能夠遍歷最終尺寸甚至超過任意尺寸(不只是列)。

0

如果這是一種常見的用例爲你的函數,它或許會是個不錯的主意列中自動使功能迭代如果輸入的是不是一個載體。

這並不完全解決您的問題,但它會簡化功能的使用。在這種情況下,輸出也應該是一個矩陣。

您還可以通過使用m(:,:) = m(:)變換矩陣一個長列。但是,這取決於你的功能,如果這是有道理的。

2

也許你可以隨時變換矩陣用「操作,然後轉換結果回來。

smoothed = smooth(input', 9)'; 

這至少與fft函數一起工作。

+0

這不會對平滑函數工作。如果通過平滑矩陣,它將它視爲一個大向量。 雖然這種方法對其他一些功能來說很方便。 – dmnd 2008-10-21 06:18:21

10

的MATLAB「爲」的聲明實際上遍歷任何的精選提供的列 - 通常情況下,這只是導致過去了成矢量標量的序列(如在你上面的例子)是一個行向量。這意味着,你可以重寫上面的代碼是這樣的:

function result = map_column(m, func) 
    result = []; 
    for m_col = m 
     result = horzcat(result, func(m_col)); 
    end 

如果FUNC不返回的列向量,那麼你可以添加類似

f = func(m_col); 
result = horzcat(result, f(:)); 

迫使它進入一列。

1

如果您正在處理大型矩陣,請不要忘記預先分配結果矩陣。否則你的CPU會花費很多週期反覆地重新分配矩陣,每次增加一個新的行/列。

1

一種導致跨矩陣的列隱式循環的方法是使用cellfun。也就是說,您必須先將矩陣轉換爲單元陣列,每個單元將保持一列。然後打電話給cellfun。例如:

A = randn(10,5);

看到這裏我已經計算出每列的標準偏差。

cellfun(@ STD,mat2cell(A,尺寸(A,1),一(1,尺寸(A,2))))

ANS = 0.78681 1.1473 0.89789 0.66635 1.3482

中當然,MATLAB中的許多函數已經設置爲按照用戶指示在數組的行或列上工作。這當然是std,但這是測試cellfun成功運行的便捷方式。

STD(A,[],1)

ANS = 0.78681 1.1473 0.89789 0.66635 1.3482

相關問題