如何在 MATLAB 中迭代 n 维矩阵中的每个元素?
我有个问题。 我需要在 MATLAB 中迭代 n 维矩阵中的每个元素。 问题是,我不知道如何对任意数量的维度执行此操作。 我知道我可以
for i = 1:size(m,1)
for j = 1:size(m,2)
for k = 1:size(m,3)
这么说,但是有没有办法对任意数量的维度做到这一点?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
另一个技巧是使用
ind2sub
和sub2ind
。 与numel
和size
结合使用,这可以让您执行如下操作,创建一个 N 维数组,然后设置“对角线”上的所有元素为 1。One other trick is to use
ind2sub
andsub2ind
. In conjunction withnumel
andsize
, this can let you do stuff like the following, which creates an N-dimensional array, and then sets all the elements on the "diagonal" to be 1.您可以让递归函数完成这项工作
L = size(M)
idx = Zeros(L,1)
length(L)
作为最大深度for idx(深度) = 1:L(深度)
length(L)
,则执行元素操作,否则调用该函数再次使用深度+1,如果您想检查所有点,则速度不如矢量化方法,但如果您不需要评估其中的大多数点,那么它可以节省大量时间。
You could make a recursive function do the work
L = size(M)
idx = zeros(L,1)
length(L)
as the maximum depthfor idx(depth) = 1:L(depth)
length(L)
, do the element operation, else call the function again withdepth+1
Not as fast as vectorized methods if you want to check all the points, but if you don't need to evaluate most of them it can be quite a time saver.
更快(约 11%)
这些解决方案比使用
numel
;)或UPD 。 tnx @rayryeng 检测到上一个答案中的错误
免责声明
由于存在基本的拼写错误,本文引用的计时信息不正确且不准确(请参阅下面的评论流以及 编辑历史记录 - 特别查看此答案的第一个版本)。 买者自负。
these solutions are more faster (about 11%) than using
numel
;)or
UPD. tnx @rayryeng for detected error in last answer
Disclaimer
The timing information that this post has referenced is incorrect and inaccurate due to a fundamental typo that was made (see comments stream below as well as the edit history - specifically look at the first version of this answer). Caveat Emptor.
如果您深入研究
size
的其他用途,您会发现实际上可以获得每个维度大小的向量。 此链接向您显示文档:www.mathworks.com/access /helpdesk/help/techdoc/ref/size.html
获取大小向量后,迭代该向量。 像这样的东西(请原谅我的语法,因为我从大学起就没有使用过 Matlab):
将其变成实际的 Matlab 合法语法,我认为它会做你想要的。
此外,您应该能够按照此处。
If you look deeper into the other uses of
size
you can see that you can actually get a vector of the size of each dimension. This link shows you the documentation:www.mathworks.com/access/helpdesk/help/techdoc/ref/size.html
After getting the size vector, iterate over that vector. Something like this (pardon my syntax since I have not used Matlab since college):
Make this into actual Matlab-legal syntax, and I think it would do what you want.
Also, you should be able to do Linear Indexing as described here.
您想要模拟 n 嵌套的 for 循环。
迭代 n 维数组可以看作是增加 n 位数字。
在每个维度上,我们有与维度长度一样多的数字。
示例:
有数组(矩阵)
假设我们在“表示法”中
:要模拟它,您必须使用“n 位数字表示法”
我们有 3 位数字,第一个数字为 3 位,第二个数字为 4 位,第五位数字为 5 位对于第三位数字
我们必须增加这个数字,所以我们会得到序列
所以你可以编写代码来增加这样的n位数字。 您可以这样做,您可以从数字的任何值开始,然后按任意数字增加/减少数字。 这样您就可以模拟从表中某处开始但不在末尾结束的嵌套 for 循环。
但这并不是一件容易的事。 不幸的是,我无法帮助解决 matlab 符号。
You want to simulate n-nested for loops.
Iterating through n-dimmensional array can be seen as increasing the n-digit number.
At each dimmension we have as many digits as the lenght of the dimmension.
Example:
Suppose we had array(matrix)
in "for notation" we have:
to simulate this you would have to use the "n-digit number notation"
We have 3 digit number, with 3 digits for first, 4 for second and five for third digit
We have to increase the number, so we would get the sequence
So you can write the code for increasing such n-digit number. You can do it in such way that you can start with any value of the number and increase/decrease the digits by any numbers. That way you can simulate nested for loops that begin somewhere in the table and finish not at the end.
This is not an easy task though. I can't help with the matlab notation unfortunaly.
您可以使用线性索引来访问每个元素。
如果您不需要知道您所在的 i、j、k,这非常有用。 但是,如果您不需要知道自己所在的索引,那么最好使用 arrayfun()
You can use linear indexing to access each element.
This is useful if you don't need to know what i,j,k, you are at. However, if you don't need to know what index you are at, you are probably better off using arrayfun()
Matlab 中数组的线性索引的思想是一个重要的思想。 MATLAB 中的数组实际上只是一个元素向量,排列在内存中。 MATLAB 允许您使用行和列索引,或单个线性索引。 例如,
我们可以通过将数组展开为向量来查看元素在内存中存储的顺序。
正如您所看到的,第 8 个元素是数字 7。实际上,函数 find 将其结果作为线性索引返回。
结果是,我们可以使用单个循环依次访问通用 nd 数组的每个元素。 例如,如果我们想要对 A 的元素进行平方(是的,我知道有更好的方法可以做到这一点),可以这样做:
在很多情况下线性索引更有用。 线性索引和二维(或更高)维下标之间的转换是通过 sub2ind 和 ind2sub 函数完成的。
线性索引一般适用于 matlab 中的任何数组。 因此,您可以在结构体、元胞数组等上使用它。线性索引的唯一问题是它们变得太大时。 MATLAB 使用 32 位整数来存储这些索引。 因此,如果数组中的元素总数超过 2^32,线性索引将会失败。 如果您经常使用稀疏矩阵,这实际上只是一个问题,有时这会导致问题。 (虽然我不使用 64 位 MATLAB 版本,但我相信对于那些使用 64 位 MATLAB 版本的幸运者来说,这个问题已经得到解决。)
The idea of a linear index for arrays in matlab is an important one. An array in MATLAB is really just a vector of elements, strung out in memory. MATLAB allows you to use either a row and column index, or a single linear index. For example,
We can see the order the elements are stored in memory by unrolling the array into a vector.
As you can see, the 8th element is the number 7. In fact, the function find returns its results as a linear index.
The result is, we can access each element in turn of a general n-d array using a single loop. For example, if we wanted to square the elements of A (yes, I know there are better ways to do this), one might do this:
There are many circumstances where the linear index is more useful. Conversion between the linear index and two (or higher) dimensional subscripts is accomplished with the sub2ind and ind2sub functions.
The linear index applies in general to any array in matlab. So you can use it on structures, cell arrays, etc. The only problem with the linear index is when they get too large. MATLAB uses a 32 bit integer to store these indexes. So if your array has more then a total of 2^32 elements in it, the linear index will fail. It is really only an issue if you use sparse matrices often, when occasionally this will cause a problem. (Though I don't use a 64 bit MATLAB release, I believe that problem has been resolved for those lucky individuals who do.)
正如其他一些答案所指出的,您可以使用 从
1
到numel(A)
的线性索引单个 for 循环。 您还可以使用几个函数:arrayfun
和cellfun
。首先假设您有一个要应用于
A
的每个元素的函数(称为my_func
)。 您首先为此创建一个函数句柄函数:如果
A
是任意维度的矩阵(double、single等类型),则可以使用arrayfun
将my_func
应用到每个元素:如果
A
是 元胞数组 为任意维度,您可以使用cellfun
将my_func
应用于每个单元:函数
my_func
必须接受A 作为输入。 如果
my_func
有任何输出,这些输出将被放置在outArgs
中,其大小/维度与A
相同。关于输出的一个警告...如果
my_func
在对A
的不同元素进行操作时返回不同大小和类型的输出,则outArgs
将具有制作成元胞数组。 这是通过使用附加参数/值对调用arrayfun
或cellfun
来完成的:As pointed out in a few other answers, you can iterate over all elements in a matrix
A
(of any dimension) using a linear index from1
tonumel(A)
in a single for loop. There are also a couple of functions you can use:arrayfun
andcellfun
.Let's first assume you have a function that you want to apply to each element of
A
(calledmy_func
). You first create a function handle to this function:If
A
is a matrix (of type double, single, etc.) of arbitrary dimension, you can usearrayfun
to applymy_func
to each element:If
A
is a cell array of arbitrary dimension, you can usecellfun
to applymy_func
to each cell:The function
my_func
has to acceptA
as an input. If there are any outputs frommy_func
, these are placed inoutArgs
, which will be the same size/dimension asA
.One caveat on outputs... if
my_func
returns outputs of different sizes and types when it operates on different elements ofA
, thenoutArgs
will have to be made into a cell array. This is done by calling eitherarrayfun
orcellfun
with an additional parameter/value pair: