你可以申请一个职能,每个项目的一个矢量由说,例如, v + 1, 或者您可以使用的功能 arrayfun.我怎么可以这样做的每一行列的矩阵,而不采用对环?

有帮助吗?

解决方案

许多内操作的喜欢 sumprod 已经能够运作的跨行或列,因此可能能够"重构"的功能的申请利用这一优势。

如果这不是一个可行的选择,做到这一点的方法之一是收集行或列入细胞的使用 mat2cellnum2cell, 然后使用 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

迷迷糊糊同时寻求已在此问题/答案如何计算一个矩阵的行和。

我只想补充一点,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) )
scroll top