在MATLAB中从数组中选择元素

4
我知道在MATLAB中,在一维情况下,您可以使用索引选择元素,例如a([1 5 3]),以返回a的第1、第5和第3个元素。我有一个二维数组,并希望根据我拥有的一组元组选择单个元素。所以我可能想要获取a(1,3)、a(1,4)、a(2,5)等等。目前最好的方法是diag(a(tuples(:,1), tuples(:,2)),但对于较大的a和/或tuples,这需要大量的内存。我必须将这些元组转换为线性索引,还是有没有更清晰的方法在不占用太多内存的情况下完成我想要的操作?

1
你可能想看一下https://dev59.com/cGkw5IYBdhLWcg3wGGm8,因为它涵盖了你所遇到的同样问题。 - Gunther Struyf
或者你可以在这里查看(http://stackoverflow.com/questions/12294232/changing-multiple-elements-of-known-coordinates-of-a-matrix-without-a-for-loop/12294606#12294606),以查看基本相同的答案。 - angainor
感谢您指出这些问题;我进行了搜索,只找到了逻辑索引的案例。 - sas4740
3个回答

6

转换为线性索引似乎是一种合法的方法:

indices = tuples(:, 1) + size(a,1)*(tuples(:,2)-1);
selection = a(indices);

请注意,这也可以在Matlab内置解决方案sub2ind中实现,正如nate'2的答案所示:
a(sub2ind(size(a), tuples(:,1),tuples(:,2)))

然而,
a = rand(50);
tuples = [1,1; 1,4; 2,5];

start = tic;
for ii = 1:1e4
    indices = tuples(:,1) + size(a,1)*(tuples(:,2)-1); end
time1 = toc(start);


start = tic;
for ii = 1:1e4
    sub2ind(size(a),tuples(:,1),tuples(:,2)); end
time2 = toc(start);

round(time2/time1)

这提供了

ans =   
    38

因此,虽然sub2ind更易于阅读,但速度也慢了大约40倍。如果您经常执行此操作,请选择上面的方法。否则,使用sub2ind来提高可读性。


1
注意:Matlab是基于1的,所以您必须使用m*(tuples(:,2)-1)。否则,这个解决方案比sub2ind快约40倍,所以我更喜欢它 :) - Rody Oldenhuis
@RodyOldenhuis 我也更喜欢这个。然而,我之前在SO上受到了轻微的批评,并且sub2ind是正确的方法。有趣的是人们会改变他们所喜欢的东西 :) - angainor
@angainor:嗯,人各有所好。我只是想知道sub2ind到底做了什么,以致于导致它需要消耗这么多时间……你知道,我们应该开发一个新的工具箱,类似于lightspeed,特别是针对这种情况 :) - Rody Oldenhuis
1
@RodyOldenhuis 你知道这个故事怎么说的:“……MATLAB必须处理一般情况,而你的情况很特殊,所以当然MATLAB会变慢……”。但实际上它更加普遍 ;) - angainor

3
如果x和y是矩阵a的x y值的向量,那么sub2und应该可以解决您的问题:
a(sub2ind(size(a),x,y))

例如

a=magic(3)

a =

 8     1     6
 3     5     7
 4     9     2
x = [3 1];
y = [1 2];


a(sub2ind(size(a),x,y))

ans =

 4     1

两种方法都不错。这个方法也可以无缝地适用于更高维度+1。尽管另一个方法执行更快。 - angainor

0

您可以将2D Matlab位置用1D数字引用,例如:

a = [3 4 5;
     6 7 8;
     9 10 11;];
a(1) = 3;
a(2) = 6;
a(6) = 10;

所以如果你能够像这样获取矩阵中的位置:

a([(col1-1)*(rowMax)+row1, (col2-1)*(rowMax)+row2, (col3-1)*(rowMax)+row3])

注意:在此情况下,rowmax为3

将会给你列1/行1、列2/行2和列3/行3的元素列表。

因此,如果

row1 = col1 = 1
row2 = col2 = 2
row3 = col3 = 3

你将会得到:

[3, 7, 11]

返回。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接