在MATLAB中从2D矩阵中提取给定每行列索引的2D矩阵的元素

时间:2017-10-12 10:23:43

标签: matlab matrix indexing

我试图从定义其索引的矩阵块重新采样我的数据。希望这个例子能说清楚:

A=rand(18400,100);
A_IDX=randi([1 100],[18400 100]);

A_IDX包含18400行和100列。我想在A索引处提取矩阵A_IDX。结果如下:

A=[1 2 3; 4 5 6];
A_IDX=[1 3; 2 3];
A_Result=[1 3; 5 6];

我试过A(:,A_IDX),但这给了我1840x184000的矩阵大小,这不是我想要做的第一个。有人可以帮忙吗?提前谢谢!

3 个答案:

答案 0 :(得分:7)

我们可以得到那些索引的线性索引等价,然后简单地索引到输入数组就可以得到所需的输出。现在,为了获得这些线性索引,我们将使用bsxfun进行与索引计算相关的数学计算,这基本上涉及缩放和偏移。

使用二维列索引进行索引

对于2D列索引,我们会有 -

function out = take_cols(a, col_idx)

n = size(a,1);
lidx = bsxfun(@plus,(col_idx-1)*n,(1:n).');
out = a(lidx);

示例运行 -

>> a
a =
    39    83    39    48    36
    58    74    20    19    50
    69    97    65    34    57
    47    58    80    24    51
>> col_idx
col_idx =
     2     4
     3     5
     1     4
     2     5
>> take_cols(a, col_idx)
ans =
    83    48
    20    50
    69    34
    58    51

使用二维行索引数组进行索引

对于2D行索引数组,它将是 -

function out = take_rows(a, row_idx)

[m,n] = size(a);
lidx = bsxfun(@plus,row_idx, (0:n-1)*m);
out = a(lidx);

示例运行 -

>> a
a =
    39    83    39    48    36
    58    74    20    19    50
    69    97    65    34    57
    47    58    80    24    51
>> row_idx
row_idx =
     3     2     3     1     2
     4     3     4     2     4
>> take_rows(a, row_idx)
ans =
    69    74    65    48    50
    47    97    80    19    51

答案 1 :(得分:2)

这个奇怪的代码怪物会给你你想要的东西。它为每个索引生成适当的下标并将它们转换为线性,然后线性地索引A

A_IDX_aux=A_IDX';
reshape(A(sub2ind(size(A),repelem(1:size(A,1),1,size(A_IDX,1)).',A_IDX_aux(:))),[size(A,1), size(A_IDX,2)]).';

答案 2 :(得分:2)

我也找到了这个任务的解决方案,但不是那么快,DivakarAnder:)

看哪:

res = cell2mat(arrayfun( @(x) A(x,A_IDX(x,:)), (1:size(A,1))', 'UniformOutput',false));

它使用cell2mat,我想它并不像bsxfun那么快,但希望仍然存在,我很想测试所有3种解决方案。而且我得到了不明显的结果!

Elapsed time is 0.000058 seconds.   % Divakar
Elapsed time is 0.000077 seconds.   % Andres
Elapsed time is 0.000339 seconds.   % Me

这意味着bsxf最快!但是使用正确的索引也会给出快速的结果!我的解决方案非常缓慢。我想这是因为'UniformOutput', false - 我被迫转换为单元格然后返回,所以它减慢了我的方法。

结论:

  1. 如果您可以使用bsxf - 请使用它!

  2. 尽管我的方法看起来比Andres看起来更令人愉悦,但它仍然较慢。

  3. 所以发表这个答案是没有任何意义的:D我花了一些时间做现在的工作,也许这将有助于将来的人

相关问题