我如何可以应用的一个函数,每一行列的一个矩阵中MATLAB?
-
22-09-2019 - |
题
你可以申请一个职能,每个项目的一个矢量由说,例如, v + 1
, 或者您可以使用的功能 arrayfun
.我怎么可以这样做的每一行列的矩阵,而不采用对环?
解决方案
许多内操作的喜欢 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函数 bsxfun 。从MATLAB文档,bsxfun“应用由功能句柄乐趣指定阵列A和B的元件由元件二进制运算,并启用单扩张。”
@gnovice该总和上述等基本功能已经在所述第一非单维操作(即,行,如果有多于一个的行,列,如果只有一个行,或如果较低维度都具有大小更高的维度== 1)。然而,bsxfun适用于任何功能,包括(尤其是)用户定义的函数。
例如,假设你有一个矩阵A和行向量B.例如,让我们说:
A = [1 2 3;
4 5 6;
7 8 9]
B = [0 1 2]
您想要的功能power_by_col其中在矢量C返回所有A中的元素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为您节省一些步骤(您无需明确计算的尺寸)。然而,在我的一些非正式的测试,事实证明,repmat大约快两倍,如果要应用的功能(就像我的幂函数,上面)很简单。所以,你需要选择是否要简单或速度。
我不能评论如何高效,这是,但这里有一个解决方案:
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)
大厦 Alex的答案,这里是一个比较通用的功能:
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没有一个功能,可以操作的数据每行而不是每件。它被称为 rowfun
(http://www.mathworks.se/help/matlab/ref/rowfun.html),但唯一的"问题",它的工作上 表 (http://www.mathworks.se/help/matlab/ref/table.html)而不是 矩阵.
添加到这个问题的答案的不断变化的性质,从r2016b,MATLAB会隐扩大单的尺寸,消除了对在许多情况下bsxfun
的需要。
从 r2016b发行说明:
隐扩展:应用逐元素的操作和功能,以阵列与长度为1
的尺寸自动膨胀隐式膨胀是标量膨胀的概括。同 标量膨胀,标量展开成为大小作为另一相同 阵列,以促进元素为单位的运算。随着隐性扩展, 逐元素运算符和函数列在这里可以隐 扩大它们的输入是相同的尺寸,只要该阵列具有 兼容大小。两个数组有兼容的尺寸,如果,每 尺寸,输入端的尺寸大小是相同或 其中之一是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)。
以前,此功能通过bsxfun功能是可用的。 现在建议你直接替换bsxfun的多数用途 呼吁支持隐扩展的功能和运营商。 相比于使用bsxfun,隐含的扩张提供更快的速度, 更好的内存使用情况,以及改进的代码的可读性。
使用最新版本的Matlab的,你可以使用表数据结构,你的优势。甚至还有一个“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)')
以上答案都不对工作“开箱即用”对我来说,但是,下面的函数,通过复制其他答案作品的思想获得:
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
接受的答案似乎是先转换到细胞,然后使用cellfun
操作在所有小区。我不知道具体的应用程序,但一般我会用想 bsxfun
一>到工作在基质会更有效。基本上bsxfun
施加操作元件逐元件跨两个阵列。所以,如果你想通过每个项目在n x 1
向量乘在m 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
的第j个元素的vec2
第i个元素。
您可以使用bsxfun
的各种内置功能,你可以声明自己。该文件有一个列表许多内置功能,但基本上你能说出它接受两个数组(向量或矩阵)作为参数的任何功能,它开始工作。
迷迷糊糊同时寻求已在此问题/答案如何计算一个矩阵的行和。
我只想补充一点,Matlab的SUM函数实际上有支持有两个维度总结对于给定的尺寸,即一个标准的矩阵。
因此,为了计算列总和做:
colsum = sum(M) % or sum(M, 1)
和用于行和,简单地做
rowsum = sum(M, 2)
我的选择是,这是比既for循环编程和转化为细胞快:)
这一切都可以在为SUM MATLAB的帮助下找到。
如果你知道你行的长度,你可以是这样的:
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) )