matlab 遍历矩阵列的最佳方法是什么?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/216341/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 16:40:43  来源:igfitidea点击:

What's the best way to iterate through columns of a matrix?

matlabmatrixenumeration

提问by dmnd

I want to apply a function to all columns in a matrix with MATLAB. For example, I'd like to be able to call smooth on every column of a matrix, instead of having smooth treat the matrix as a vector (which is the default behaviour if you call smooth(matrix)).

我想使用 MATLAB 将函数应用于矩阵中的所有列。例如,我希望能够在矩阵的每一列上调用 smooth,而不是将矩阵视为向量(如果调用 ,这是默认行为smooth(matrix))。

I'm sure there must be a more idiomatic way to do this, but I can't find it, so I've defined a map_columnfunction:

我确定一定有更惯用的方法来做到这一点,但我找不到它,所以我定义了一个map_column函数:

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

which I can call with:

我可以打电话给:

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

Is there anything wrong with this code? How could I improve it?

这段代码有什么问题吗?我该如何改进它?

采纳答案by Mr Fooz

Your solution is fine.

你的解决方案很好。

Note that horizcat exacts a substantial performance penalty for large matrices. It makes the code be O(N^2) instead of O(N). For a 100x10,000 matrix, your implementation takes 2.6s on my machine, the horizcat one takes 64.5s. For a 100x5000 matrix, the horizcat implementation takes 15.7s.

请注意,horizcat 对大型矩阵造成了显着的性能损失。它使代码成为 O(N^2) 而不是 O(N)。对于 100x10,000 矩阵,您的实现在我的机器上需要 2.6 秒,horizcat 需要 64.5 秒。对于 100x5000 矩阵,horizcat 实现需要 15.7 秒。

If you wanted, you could generalize your function a little and make it be able to iterate over the final dimension or even over arbitrary dimensions (not just columns).

如果需要,您可以稍微概括一下您的函数,使其能够迭代最终维度甚至任意维度(不仅仅是列)。

回答by Tim Whitcomb

The MATLAB "for" statement actually loops over the columns of whatever's supplied - normally, this just results in a sequence of scalars since the vector passed into for (as in your example above) is a row vector. This means that you can rewrite the above code like this:

MATLAB“for”语句实际上循环了所提供的任何列 - 通常,这只会产生一系列标量,因为传入 for 的向量(如上面的示例中所示)是一个行向量。这意味着你可以像这样重写上面的代码:

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

If func does not return a column vector, then you can add something like

如果 func 不返回列向量,那么您可以添加类似

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

to force it into a column.

将其强制为一列。

回答by Hallgrim

Maybe you could always transform the matrix with the ' operator and then transform the result back.

也许您总是可以使用 ' 运算符转换矩阵,然后将结果转换回来。

smoothed = smooth(input', 9)';

That at least works with the fft function.

这至少适用于 fft 功能。

回答by Hallgrim

A way to cause an implicit loop across the columns of a matrix is to use cellfun. That is, you must first convert the matrix to a cell array, each cell will hold one column. Then call cellfun. For example:

在矩阵的列之间引起隐式循环的一种方法是使用 cellfun。也就是说,您必须首先将矩阵转换为单元格数组,每个单元格将包含一列。然后调用cellfun。例如:

A = randn(10,5);

See that here I've computed the standard deviation for each column.

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

cellfun(@std,mat2cell(A,size(A,1),ones(1,size(A,2))))

ans =
      0.78681       1.1473      0.89789      0.66635       1.3482

Of course, many functions in MATLAB are already set up to work on rows or columns of an array as the user indicates. This is true of std of course, but this is a convenient way to test that cellfunworked successfully.

当然,MATLAB 中的许多函数已经设置为按照用户指示处理数组的行或列。这当然适用于 std,但这是一种测试cellfun成功的便捷方法。

std(A,[],1)

ans =
      0.78681       1.1473      0.89789      0.66635       1.3482

回答by Jason S

Don't forget to preallocate the result matrix if you are dealing with large matrices. Otherwise your CPU will spend lots of cycles repeatedly re-allocating the matrix every time it adds a new row/column.

如果您正在处理大型矩阵,请不要忘记预先分配结果矩阵。否则,每次添加新行/列时,您的 CPU 将花费大量周期反复重新分配矩阵。

回答by bastibe

If this is a common use-case for your function, it would perhaps be a good idea to make the function iterate through the columns automatically if the input is not a vector.

如果这是您的函数的常见用例,那么在输入不是向量的情况下,让函数自动遍历列可能是个好主意。

This doesn't exactly solve your problem but it would simplify the functions' usage. In that case, the output should be a matrix, too.

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

You can also transform the matrix to one long column by using m(:,:) = m(:). However, it depends on your function if this would make sense.

您还可以使用 将矩阵转换为一长列m(:,:) = m(:)。但是,这是否有意义取决于您的功能。