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

从MATLAB中的2D矩阵中提取给定2D矩阵的元素,该矩阵为每行的列索引,matlab,matrix,indexing,Matlab,Matrix,Indexing,我试图从定义索引的矩阵块中重新采样数据。希望这个例子能说明: A=rand(18400,100); A_IDX=randi([1 100],[18400 100]); A_IDX由18400行和100列组成。我想在A_IDX索引处提取矩阵A。结果可能是: A=[1 2 3; 4 5 6]; A_IDX=[1 3; 2 3]; A_Result=[1 3; 5 6]; 我尝试了A(:,aidx),但这给了我1840x184000矩阵大小,这不是我一开始想要做的。有人能帮忙吗?提前谢谢 我们可以

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

A=rand(18400,100);
A_IDX=randi([1 100],[18400 100]);
A_IDX
由18400行和100列组成。我想在
A_IDX
索引处提取矩阵
A
。结果可能是:

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

我尝试了
A(:,aidx)
,但这给了我1840x184000矩阵大小,这不是我一开始想要做的。有人能帮忙吗?提前谢谢

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

使用二维列索引数组编制索引

对于
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
>> 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
使用二维行索引数组编制索引

对于行索引的
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
>> 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
>> 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

这个奇怪的代码怪物会给你你想要的。它为每个索引生成适当的下标,并将其转换为线性,然后只对
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)]).';

我也找到了这项任务的解决方案,但速度不如和:)

瞧:

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
-我被迫转换为单元格,然后再转换回来,所以这大大降低了我的方法的速度

结论:

  • 如果您可以使用bsxf,请使用它

  • 尽管我的方法看起来比安德烈斯的方法在视觉上更令人愉悦,但它仍然较慢

  • 所以,发布这样的答案毫无意义:D我花一些时间在当前的工作上,也许这会对将来的人有所帮助


  • 那么
    A_IDX
    每行
    A
    都有列索引,对吗?我假设你总是需要相同数量的列,每行是的,你是对的。很抱歉忘了提到这一点。嗯,这比我的mosntrosuityDivakar要好得多,如果
    col\u idx
    是一个逻辑矩阵而不是索引呢?例如,
    a=rand(2,5)
    b=rand(2,5)
    c=a>b
    提取a=a(:,c)
    。每次都会出现索引超出维度的错误。我应该知道这里有什么吗?@GregorIsack那里的预期输出是什么?有了遮罩,你就失去了2D格式,如果你这样做的话,那就减少了遮罩数组:
    a(c)
    为1D数组。哇哦。我要把代码分开,太让我困惑了:p。我从未听说过
    repelem
    命令。只是好奇,它比repmat好吗?@GregorIsack它不同。Repelem重复每个元素!只有更新版本才有。然而,Divakars的答案是waaaay比我的好,明白了。我会调查两者的!非常感谢你!嗯,这项努力值得一些支持;)