例如,您可以對矢量中的每個項目應用函數,例如,v + 1
,或者您可以使用函數arrayfun
。如何在不使用for循環的情況下爲矩陣的每一行/列做到這一點?如何將函數應用於MATLAB中矩陣的每一行/列?
回答
許多內置操作如sum
和prod
已能夠跨行或列操作,因此您可以重構正在應用的函數以利用此功能。
如果這不是一個可行的選擇,一分做它用mat2cell
或num2cell
收集行或列進入細胞,然後使用cellfun
所得到的單元陣列上運行的方式。
作爲一個例子,假設您想對矩陣的列進行求和M
。爲此,您可以簡單地使用sum
:
M = magic(10); %# A 10-by-10 matrix
columnSums = sum(M, 1); %# A 1-by-10 vector of sums for each column
這裏是你將如何使用更復雜的num2cell
/cellfun
選項做到這一點:
M = magic(10); %# A 10-by-10 matrix
C = num2cell(M, 1); %# Collect the columns into cells
columnSums = cellfun(@sum, C); %# A 1-by-10 vector of sums for each cell
就這個問題/答案迷迷糊糊的,同時尋求如何計算矩陣的行和。
我只想補充一點,Matlab的SUM函數實際上支持對給定維度進行求和,即具有兩個維度的標準矩陣。
所以計算列總和做到:
colsum = sum(M) % or sum(M, 1)
與該行資金,根本就
rowsum = sum(M, 2)
我敢打賭,這是快於既爲循環編程並轉換到細胞:)
所有這一切都可以在MATLAB的MATLAB幫助中找到。
我不能就如何高效,這是的,但在這裏評論的一個解決方案:
applyToGivenRow = @(func, matrix) @(row) func(matrix(row, :))
applyToRows = @(func, matrix) arrayfun(applyToGivenRow(func, matrix), 1:size(matrix,1))'
% Example
myMx = [1 2 3; 4 5 6; 7 8 9];
myFunc = @sum;
applyToRows(myFunc, myMx)
給出一個更通用的答案[這裏](http://stackoverflow.com/a/15971182/376454)。 – Wok 2013-04-12 12:28:31
大廈Alex's answer,這裏是一個比較通用的功能:
applyToGivenRow = @(func, matrix) @(row) func(matrix(row, :));
newApplyToRows = @(func, matrix) arrayfun(applyToGivenRow(func, matrix), 1:size(matrix,1), 'UniformOutput', false)';
takeAll = @(x) reshape([x{:}], size(x{1},2), size(x,1))';
genericApplyToRows = @(func, matrix) takeAll(newApplyToRows(func, matrix));
這裏的比較這兩個函數:
>> % Example
myMx = [1 2 3; 4 5 6; 7 8 9];
myFunc = @(x) [mean(x), std(x), sum(x), length(x)];
>> genericApplyToRows(myFunc, myMx)
ans =
2 1 6 3
5 1 15 3
8 1 24 3
>> applyToRows(myFunc, myMx)
??? Error using ==> arrayfun
Non-scalar in Uniform output, at index 1, output 1.
Set 'UniformOutput' to false.
Error in ==> @(func,matrix)arrayfun(applyToGivenRow(func,matrix),1:size(matrix,1))'
你可能想要更晦澀的Matlab函數bsxfun。從Matlab文檔中,bsxfun「將由函數handle fun指定的逐個元素的二進制操作應用於數組A和B,並啓用單例擴展。」
@gnovice上面陳述的是,sum和其他基本函數已經在第一個非單實體維度上操作(即,如果有多行,行如果只有一行,則列;或者如果較低維度都具有更高維度大小== 1)。但是,bsxfun適用於任何函數,包括(特別是)用戶定義的函數。
例如,假設你有一個矩陣A和行向量求,讓我們說:
A = [1 2 3;
4 5 6;
7 8 9]
B = [0 1 2]
你想要的功能power_by_col它在一個載體下,在所有元素返回的力量B.
從上面的例子中的相應列中,C是一個3×3矩陣:
C = [1^0 2^1 3^2;
4^0 5^1 6^2;
7^0 8^1 9^2]
即
C = [1 2 9;
1 5 36;
1 8 81]
你能做到這一點的強制方法使用repmat:
C = A.^repmat(B, size(A, 1), 1)
或者你可以使用bsxfun,在內部採取repmat步驟護理做到這一點優雅的方式:
C = bsxfun(@(x,y) x.^y, A, B)
所以bsxfun爲您節省了一些步驟(您不需要明確計算A的尺寸)。然而,在我的一些非正式測試中,事實證明,如果要應用的功能(如上面的功率函數)很簡單,repmat的速度大概是它的兩倍。所以你需要選擇你是想要簡單還是速度。
接受的答案似乎是首先轉換爲單元格,然後使用cellfun
來操作所有單元格。我不知道具體的應用,但總的來說,我認爲使用bsxfun
在矩陣上運行會更有效率。基本上bsxfun
跨兩個數組應用一個元素操作。所以,如果你想通過每個項目在m x 1
向量乘在n x 1
向量中的每個項目獲得的n x m
數組,你可以使用:
vec1 = [ stuff ]; % n x 1 vector
vec2 = [ stuff ]; $ m x 1 vector
result = bsxfun('times', vec1.', vec2);
這會給你一個矩陣稱爲result
其中(I,J)入口將是vec1
的第i個元素乘以vec2
的第j個元素。
對於各種內置函數,您可以使用bsxfun
,並且您可以聲明自己的函數。該文檔包含許多內置函數的列表,但基本上可以將任何接受兩個數組(矢量或矩陣)的函數命名爲參數並使其起作用。
,如果你知道你行的長度可以讓這樣的事情:
a=rand(9,3);
b=rand(9,3);
arrayfun(@(x1,x2,y1,y2,z1,z2) line([x1,x2],[y1,y2],[z1,z2]) , a(:,1),b(:,1),a(:,2),b(:,2),a(:,3),b(:,3))
對於看到這個答案的人:這不是做這件事的方法!這不是在MATLAB中做任何事情的方法! – 2016-08-10 12:12:06
對於完整性/利益,我想補充一點,MATLAB確實有一個功能,可以讓您在每一個數據操作而不是每個元素。它被稱爲rowfun
(http://www.mathworks.se/help/matlab/ref/rowfun.html),但唯一的「問題」是它在表(http://www.mathworks.se/help/matlab/ref/table.html)上操作,而不是矩陣。
使用最新版本的Matlab,您可以使用Table數據結構來獲得優勢。甚至還有一個「rowfun」操作,但我發現它只是更容易做到這一點:
a = magic(6);
incrementRow = cell2mat(cellfun(@(x) x+1,table2cell(table(a)),'UniformOutput',0))
或這裏的一老一我不需要表,爲老年人Matlab的版本。
dataBinner = cell2mat(arrayfun(@(x) Binner(a(x,:),2)',1:size(a,1),'UniformOutput',0)')
添加到答案的性質演變到這個問題,開始r2016b,MATLAB會隱擴大單維度,在許多情況下不再需要爲bsxfun
。
隱擴展:應用逐元素的操作和功能與長度的尺寸自動膨脹到陣列1
隱膨脹是標量膨脹的概括。通過標量擴展,標量擴展爲與另一個 數組相同的尺寸,以便於元素操作。通過隱式擴展,只要數組具有 兼容大小,這裏列出的按元素運算符和函數就可以隱式地將其輸入擴展爲相同大小。如果對於每個維度,輸入的維度大小相同,或者其中一個維度大小爲 ,則兩個陣列具有兼容的大小。有關更多信息,請參閱基本操作的兼容陣列大小和 陣列與矩陣運算。
Element-wise arithmetic operators — +, -, .*, .^, ./, .\ Relational operators — <, <=, >, >=, ==, ~= Logical operators — &, |, xor Bit-wise functions — bitand, bitor, bitxor Elementary math functions — max, min, mod, rem, hypot, atan2, atan2d
例如,可以計算各列的均值以矩陣A, 然後從每一列與減去平均值的矢量A - 平均值(A)。
此前,此功能可通過bsxfun函數獲得。 現在建議您將大多數使用bsxfun的調用替換爲直接調用 調用支持隱式擴展的函數和運算符。 與使用bsxfun相比,隱式擴展提供更快的速度,更好的內存使用以及更高的代碼可讀性。
上述答案的工作「開箱即用」對我來說,但是,下面的函數,通過複製其他答案的想法得到工作:
apply_func_2_cols = @(f,M) cell2mat(cellfun(f,num2cell(M,1), 'UniformOutput',0));
它需要一個功能f
並將其應用於矩陣M
的每一列。
因此,例如:
f = @(v) [0 1;1 0]*v + [0 0.1]';
apply_func_2_cols(f,[0 0 1 1;0 1 0 1])
ans =
0.00000 1.00000 0.00000 1.00000
0.10000 0.10000 1.10000 1.10000
- 1. 如何將matlab擬合函數應用於矩陣的每一行
- 2. MatLab - 對矩陣中的每一行應用一個函數
- 3. 將函數應用於矩陣或數據幀的每一行
- 4. 如何在MATLAB中將函數應用於矩陣?
- 5. 將索引函數應用於矩陣行中的每個值
- 6. 如何按列將函數應用於矩陣列表
- 7. 如何將隨機數應用於矩陣中的每個單元格 - Matlab
- 8. Python Numpy將旋轉矩陣應用於陣列中的每一行
- 9. 在Matlab中對矩陣的每個元素應用函數
- 10. 如何使用Matlab將矩陣中的每n行平坦化?
- 11. 將矩陣中的每列乘以另一個矩陣中的相應行,並在Matlab中求和結果
- 12. 如何將列矩陣轉換爲行矩陣在MATLAB
- 13. 將傳遞函數應用於矩陣的每個元素
- 14. 如何將函數應用於SparkR中的每一行?
- 15. 矩陣上的函數是否應用於整個矩陣或Fortran中的每一行?
- 16. MATLAB函數矩陣參數
- 17. 如何使用廣播將一個矩陣的每一行復制到另一個矩陣的每隔一行?
- 18. 如何在MATLAB中爲矩陣中的每列添加每列中的元素?
- 19. Matlab - 矩陣陣列
- 20. MATLAB:在基質B由行乘以在矩陣的每一列
- 21. 將函數應用於data.frame的每一行並保留列類
- 22. Matlab:如何在矩陣上應用點方向函數?
- 23. Matlab,如何比較行矩陣的每個元素與另一行矩陣的每個元素?
- 24. 如何從matlab中矩陣的每一列中選擇一個元素?
- 25. 如何在matlab中將矩陣的行數減半?
- 26. Matlab:如何將數據讀入矩陣
- 27. 如何將矩陣應用於圖像
- 28. 在C++中使用Matlab函數(用於矩陣搜索)
- 29. 矩陣矩陣在Matlab中的數組?
- 30. 將函數應用於numpy數組中的每一行?
我將測試該方法的性能針對簡單for循環任何特定的情況下,這可能會更快然後轉換矩陣單元陣列。使用tic/tac wrap來測試。 – yuk 2010-02-21 23:13:03
@yuk:我認爲你的意思是「tic/toc」。 ;) – gnovice 2010-02-22 05:43:43
哎呀,當然!只是在滴答...... :) – yuk 2010-02-22 15:05:29