在MATLAB中迭代矩阵列的最佳方式是什么?

问题描述:

我想用MATLAB将函数应用于矩阵中的所有列。例如,我希望能够在矩阵的每一列调用平滑,而不是平滑地将矩阵视为向量(如果调用smooth(矩阵),则这是默认行为)。在MATLAB中迭代矩阵列的最佳方式是什么?

我敢肯定,必须有这样做的更地道的方式,但我不能找到它,所以我定义的map_column功能:

function result= map_column(m, func) 
    result= m; 
    for col= 1:size(m,2) 
     result(:,col)= func(m(:,col)); 
    end 
end 

,我可以打电话:

smoothed= map_column(input, @(c) (smooth(c, 9))); 

有什么不对的代码?我怎么能改进它?

您的解决方案很好。

请注意,对于大型矩阵,horizcat会造成实质性的损失。它使代码为O(N^2)而不是O(N)。对于一个100x10,000的矩阵,我的机器上的实现需要2.6s,horizcat需要64.5s。对于100x5000矩阵,horizcat实现需要15.7s。

如果你愿意,你可以概括你的函数一点,使之能够遍历最终尺寸甚至超过任意尺寸(不只是列)。

如果这是一种常见的用例为你的函数,它或许会是个不错的主意列中自动使功能迭代如果输入的是不是一个载体。

这并不完全解决您的问题,但它会简化功能的使用。在这种情况下,输出也应该是一个矩阵。

您还可以通过使用m(:,:) = m(:)变换矩阵一个长列。但是,这取决于你的功能,如果这是有道理的。

也许你可以随时变换矩阵用“操作,然后转换结果回来。

smoothed = smooth(input', 9)'; 

这至少与fft函数一起工作。

+0

这不会对平滑函数工作。如果通过平滑矩阵,它将它视为一个大向量。 虽然这种方法对其他一些功能来说很方便。 – dmnd 2008-10-21 06:18:21

的MATLAB“为”的声明实际上遍历任何的精选提供的列 - 通常情况下,这只是导致过去了成矢量标量的序列(如在你上面的例子)是一个行向量。这意味着,你可以重写上面的代码是这样的:

function result = map_column(m, func) 
    result = []; 
    for m_col = m 
     result = horzcat(result, func(m_col)); 
    end 

如果FUNC不返回的列向量,那么你可以添加类似

f = func(m_col); 
result = horzcat(result, f(:)); 

迫使它进入一列。

如果您正在处理大型矩阵,请不要忘记预先分配结果矩阵。否则你的CPU会花费很多周期反复地重新分配矩阵,每次增加一个新的行/列。

一种导致跨矩阵的列隐式循环的方法是使用cellfun。也就是说,您必须先将矩阵转换为单元阵列,每个单元将保持一列。然后打电话给cellfun。例如:

A = randn(10,5);

看到这里我已经计算出每列的标准偏差。

cellfun(@ STD,mat2cell(A,尺寸(A,1),一(1,尺寸(A,2))))

ANS = 0.78681 1.1473 0.89789 0.66635 1.3482

中当然,MATLAB中的许多函数已经设置为按照用户指示在数组的行或列上工作。这当然是std,但这是测试cellfun成功运行的便捷方式。

STD(A,[],1)

ANS = 0.78681 1.1473 0.89789 0.66635 1.3482