如何将函数应用于 MATLAB 中矩阵的每一行/列?
您可以将函数应用于向量中的每个项目,例如,v + 1
,或者您可以使用函数arrayfun
。如何在不使用 for 循环的情况下对矩阵的每一行/列执行此操作?
You can apply a function to every item in a vector by saying, for example, v + 1
, or you can use the function arrayfun
. How can I do it for every row/column of a matrix without using a for loop?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(13)
为了完整性/兴趣,我想补充一点,matlab 确实有一个函数,允许您对每行而不是每个元素的数据进行操作。它称为
rowfun
(http://www.mathworks .se/help/matlab/ref/rowfun.html),但唯一的“问题”是它在表上运行(http://www.mathworks.se/help/matlab/ref/table.html)而不是矩阵< /强>。For completeness/interest I'd like to add that matlab does have a function that allows you to operate on data per-row rather than per-element. It is called
rowfun
(http://www.mathworks.se/help/matlab/ref/rowfun.html), but the only "problem" is that it operates on tables (http://www.mathworks.se/help/matlab/ref/table.html) rather than matrices.除了这个问题答案的不断演变之外,从 r2016b 开始,MATLAB 将隐式扩展单例维度,在许多情况下不再需要
bsxfun
。来自 r2016b 发行说明:
Adding to the evolving nature of the answer to this question, starting with r2016b, MATLAB will implicitly expand singleton dimensions, removing the need for
bsxfun
in many cases.From the r2016b release notes:
上述答案对我来说都不是“开箱即用”的,但是,通过复制其他答案的想法获得的以下函数有效:
它采用函数
f
并将其应用于每一列矩阵M
。例如:
None of the above answers worked "out of the box" for me, however, the following function, obtained by copying the ideas of the other answers works:
It takes a function
f
and applies it to every column of the matrixM
.So for example:
使用最新版本的 Matlab,您可以使用表数据结构来发挥自己的优势。甚至还有一个“rowfun”操作,但我发现这样做更容易:
或者这里有一个旧的操作,不需要表格,适用于旧的 Matlab 版本。
With recent versions of Matlab, you can use the Table data structure to your advantage. There's even a 'rowfun' operation but I found it easier just to do this:
or here's an older one I had that doesn't require tables, for older Matlab versions.
接受的答案似乎是首先转换为单元格,然后使用 cellfun 对所有单元格进行操作。我不知道具体的应用,但一般来说我会认为使用
bsxfun
对矩阵进行操作会更高效。基本上,bsxfun
在两个数组中逐个元素地应用操作。因此,如果您想将nx 1
向量中的每个项目乘以mx 1
向量中的每个项目以获得nx m
数组,您可以可以使用:这将为您提供名为
result
的矩阵,其中 (i, j) 条目将是vec1
的第 i 个元素乘以vec2< 的第 j 个元素/代码>。
您可以将
bsxfun
用于各种内置函数,并且可以声明自己的函数。该文档列出了许多内置函数,但基本上您可以命名任何接受两个数组(向量或矩阵)作为参数的函数并使其工作。The accepted answer seems to be to convert to cells first and then use
cellfun
to operate over all of the cells. I do not know the specific application, but in general I would think usingbsxfun
to operate over the matrix would be more efficient. Basicallybsxfun
applies an operation element-by-element across two arrays. So if you wanted to multiply each item in ann x 1
vector by each item in anm x 1
vector to get ann x m
array, you could use:This will give you matrix called
result
wherein the (i, j) entry will be the ith element ofvec1
multiplied by the jth element ofvec2
.You can use
bsxfun
for all sorts of built-in functions, and you can declare your own. The documentation has a list of many built-in functions, but basically you can name any function that accepts two arrays (vector or matrix) as arguments and get it to work.我喜欢
splitapply
,它允许使用splitapply(fun,A,1:size(A,2))< 将函数应用于
A
的列/代码>。例如,
要将函数应用于行,您可以使用
splitapply(fun, A', 1:size(A,1))';
(此解决方案的来源是 此处。)
I like
splitapply
, which allows a function to be applied to the columns ofA
usingsplitapply(fun,A,1:size(A,2))
.For example
To apply the function to the rows, you could use
splitapply(fun, A', 1:size(A,1))';
(My source for this solution is here.)
您仍然可以使用 arrayfun 。
但是,按列时
splitapply
会更短。You can still use
arrayfun
too.But,
splitapply
is shorter when by column.在寻求如何计算矩阵的行和时偶然发现了这个问题/答案。
我想补充一点,Matlab 的 SUM 函数实际上支持给定维度(即二维标准矩阵)求和。
因此,要计算列总和,只需执行以下操作:
对于行总和,只需执行以下操作:
我敢打赌,这比编写 for 循环和转换为单元格要快:)
所有这些都可以在 SUM 的 matlab 帮助中找到。
Stumbled upon this question/answer while seeking how to compute the row sums of a matrix.
I would just like to add that Matlab's SUM function actually has support for summing for a given dimension, i.e a standard matrix with two dimensions.
So to calculate the column sums do:
and for the row sums, simply do
My bet is that this is faster than both programming a for loop and converting to cells :)
All this can be found in the matlab help for SUM.
如果你知道行的长度,你可以做这样的事情:
if you know the length of your rows you can make something like this:
许多内置运算,如
sum
和prod
已经能够跨行操作或列,因此您可以重构您正在应用的函数以利用这一点。如果这不是一个可行的选择,一种方法是使用
mat2cell
或num2cell
,然后使用cellfun
对生成的元胞数组进行操作。举个例子,假设您想要对矩阵
M
的列求和。您只需使用sum
即可完成此操作:以下是如何使用更复杂的
num2cell
/cellfun
选项:Many built-in operations like
sum
andprod
are already able to operate across rows or columns, so you may be able to refactor the function you are applying to take advantage of this.If that's not a viable option, one way to do it is to collect the rows or columns into cells using
mat2cell
ornum2cell
, then usecellfun
to operate on the resulting cell array.As an example, let's say you want to sum the columns of a matrix
M
. You can do this simply usingsum
:And here is how you would do this using the more complicated
num2cell
/cellfun
option:您可能需要更晦涩的 Matlab 函数 bsxfun。根据 Matlab 文档,bsxfun“将函数句柄 fun 指定的逐元素二元运算应用于数组 A 和 B,并启用单例扩展。”
@gnovice 上面指出 sum 和其他基本函数已经在第一个非单一维度上运行(即,如果有多于一行,则为行;如果只有一行,则为列;如果较低维度都具有 size==1,则为较高维度) )。但是,bsxfun 适用于任何函数,包括(尤其是)用户定义的函数。
例如,假设您有一个矩阵 A 和一个行向量 BEg,假设:
您需要一个函数 power_by_col,它在向量 C 中返回 A 中的所有元素的 B 相应列的幂。
从上面的示例中, C 是一个 3x3 矩阵:
即,
您可以使用repmat以强力方式执行此操作:
或者您可以使用bsxfun以优雅的方式执行此操作,bsxfun在内部处理repmat步骤:
因此bsxfun为您节省了一些步骤(您不需要需要显式计算 A) 的尺寸。然而,在我的一些非正式测试中,结果表明,如果要应用的函数(如上面的幂函数)很简单,repmat 的速度大约是原来的两倍。因此,您需要选择是想要简单性还是速度。
You may want the more obscure Matlab function bsxfun. From the Matlab documentation, bsxfun "applies the element-by-element binary operation specified by the function handle fun to arrays A and B, with singleton expansion enabled."
@gnovice stated above that sum and other basic functions already operate on the first non-singleton dimension (i.e., rows if there's more than one row, columns if there's only one row, or higher dimensions if the lower dimensions all have size==1). However, bsxfun works for any function, including (and especially) user-defined functions.
For example, let's say you have a matrix A and a row vector B. E.g., let's say:
You want a function power_by_col which returns in a vector C all the elements in A to the power of the corresponding column of B.
From the above example, C is a 3x3 matrix:
i.e.,
You could do this the brute force way using repmat:
Or you could do this the classy way using bsxfun, which internally takes care of the repmat step:
So bsxfun saves you some steps (you don't need to explicitly calculate the dimensions of A). However, in some informal tests of mine, it turns out that repmat is roughly twice as fast if the function to be applied (like my power function, above) is simple. So you'll need to choose whether you want simplicity or speed.
我无法评论这有多高效,但这里有一个解决方案:
I can't comment on how efficient this is, but here's a solution:
基于 Alex 的回答,这里有一个更通用的函数:
这是两个函数之间的比较:
Building on Alex's answer, here is a more generic function:
Here is a comparison between the two functions: