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
23
你可能想要更模糊的Matlab函数bsxfun . 从Matlab文档中,bsxfun "applies the element-by-element binary operation specified by the function handle fun to arrays A and B, with singleton expansion enabled."
接受的答案似乎是首先转换为单元格然后使用 cellfun 来操作所有单元格 . 我不知道具体的应用,但总的来说我认为使用bsxfun来操作矩阵会更有效率 . 基本上 bsxfun 跨两个数组逐个元素地应用操作 . 因此,如果您想将 m 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 的第i个元素乘以 vec2 的第j个元素 .
11 回答
许多内置操作(如sum和prod)已经可以跨行或列操作,因此您可以重构您正在应用的函数以利用此功能 .
如果这不是一个可行的选项,一种方法是使用mat2cell或num2cell将行或列收集到单元格中,然后使用cellfun对生成的单元格数组进行操作 .
举个例子,假设您要对矩阵
M
的列求和 . 您只需使用sum即可完成此操作:以下是使用更复杂的num2cell / cellfun选项执行此操作的方法:
你可能想要更模糊的Matlab函数bsxfun . 从Matlab文档中,bsxfun "applies the element-by-element binary operation specified by the function handle fun to arrays A and B, with singleton expansion enabled."
@gnovice在上面说过,sum和其他基本函数已经在第一个非单一维度上运行(即,如果有多个行,则为行;如果只有一行,则为列;如果较低的维度都具有大小,则为更高的维度== 1 ) . 但是,bsxfun适用于任何功能,包括(尤其)用户定义的功能 .
例如,假设你有一个矩阵A和一个行向量B.例如,让我们说:
你想要一个函数power_by_col,它在向量C中返回A中所有元素到B的相应列的幂 .
从上面的例子中,C是3x3矩阵:
即,
你可以使用repmat以蛮力的方式做到这一点:
或者您可以使用bsxfun以优雅的方式执行此操作,bsxfun在内部负责repmat步骤:
所以bsxfun会为你节省一些步骤(你不需要明确地计算A的尺寸) . 然而,在我的一些非正式测试中,事实证明,如果要应用的函数(如上面的幂函数)很简单,repmat的速度大约是其两倍 . 因此,您需要选择是否需要简单性或速度 .
我无法评论这是多么有效,但这是一个解决方案:
在Alex's answer的基础上,这是一个更通用的功能:
这是两个函数之间的比较:
为了完整性/兴趣,我想补充一点,matlab确实有一个函数,允许你对每行数据而不是每个元素进行操作 . 它被称为
rowfun
(http://www.mathworks.se/help/matlab/ref/rowfun.html),但唯一的"problem"是它在 tables (http://www.mathworks.se/help/matlab/ref/table.html)而不是 matrices 上运行 .从r2016b开始,MATLAB将隐式地扩展单个维度,在许多情况下不需要
bsxfun
,从而增加了这个问题答案的演变性质 .来自r2016b release notes:
关系运算符 - <,<=,>,> =,==,〜=
逻辑运算符 - &,|,xor
逐位函数 - bitand,bitor,bitxor
基本数学函数 - max,min,mod,rem,hypot,atan2,atan2d
例如,您可以计算矩阵A中每列的平均值,然后用A - 均值(A)减去每列的平均值向量 . 以前,此功能可通过bsxfun函数获得 . 现在建议您使用直接调用支持隐式扩展的函数和运算符来替换bsxfun的大多数用法 . 与使用bsxfun相比,隐式扩展提供更快的速度,更好的内存使用和更高的代码可读性 .
使用最新版本的Matlab,您可以使用Table数据结构 . 甚至还有'rowfun'操作但我发现这样做更容易:
或者这是一个较旧的,我不需要表格,对于较旧的Matlab版本 .
接受的答案似乎是首先转换为单元格然后使用
cellfun
来操作所有单元格 . 我不知道具体的应用,但总的来说我认为使用bsxfun来操作矩阵会更有效率 . 基本上bsxfun
跨两个数组逐个元素地应用操作 . 因此,如果您想将m x 1
向量中的每个项目乘以m x 1
向量中的每个项目以获得n x m
数组,则可以使用:这将为您提供一个名为
result
的矩阵,其中(i,j)条目将是vec1
的第i个元素乘以vec2
的第j个元素 .您可以将
bsxfun
用于各种内置函数,并且可以声明自己的函数 . 该文档有许多内置函数的列表,但基本上你可以命名任何接受两个数组(向量或矩阵)作为参数的函数,并让它工作 .对于我来说,上述答案都没有“开箱即用”,但是,通过复制其他答案的想法获得的以下功能有效:
它需要一个函数
f
并将其应用于矩阵M
的每一列 .例如:
在寻求如何计算矩阵的行和时,偶然发现了这个问题/答案 .
我想补充一点,Matlab的SUM函数实际上支持给定维度的求和,即具有二维的标准矩阵 .
所以要计算列总和:
对于行和,简单地做
我敢打赌,这比编程for循环和转换为单元格要快得多:)
所有这些都可以在matlab的matlab帮助中找到 .
如果你知道你的行的长度,你可以做这样的事情: