【问题标题】:Position of integers in vector向量中整数的位置
【发布时间】:2016-08-21 03:50:46
【问题描述】:

我认为这个问题很基本,但一段时间以来我仍然很忙。

假设我们有一个随机重复的包含 4 个整数的向量,例如:

v = [ 1 3 3 3 4 2 1 2 3 4 3 2 1 4 3 3 4 2 2] 

我正在搜索每个整数的所有位置的向量,例如对于 1,它应该是一个向量,例如:

position_one = [1 7 13]

由于我想搜索 100x10000 矩阵的每一行,我无法处理线性索引。

提前致谢!

【问题讨论】:

  • position_one = find(v==1) 会为您完成这项工作,还是您需要更复杂的东西?
  • 我的 find 问题是 sub2ind 的线性索引有问题,我不知道为什么;)但我会尝试第二个答案,因为我已经开始了类似的事情...... ..感谢您的帮助!

标签: matlab matrix indexing


【解决方案1】:

行和列

由于每个整数的输出都会发生变化,因此元胞数组将适合整个任务。对于整个矩阵,您可以执行以下操作:

A = randi(4,10,30); % some data
Row = repmat((1:size(A,1)).',1,size(A,2)); % index of the row
Col = repmat((1:size(A,2)),size(A,1),1); % index of the column
pos = @(n) [Row(A==n) Col(A==n)]; % Anonymous function to find the indices of 'n'

比你可以写的每个n

>> pos(3)
ans =
     1     1
     2     1
     5     1
     6     1
     9     1
     8     2
     3     3
     .     .
     .     .
     .     .

其中第一列是行,第二列是A 中每个n 实例的列。

对于所有ns,您可以使用arrayfun

positions = arrayfun(pos,1:max(A(:)),'UniformOutput',false) % a loop that goes over all n's

或简单的for 循环(更快):

positions = cell(1,max(A(:)));
for n = 1:max(A(:))
    positions(n) = {pos(n)};
end

两种情况下的输出都是元胞数组:

positions = 
    [70x2 double]    [78x2 double]    [76x2 double]    [76x2 double]

对于每个n,你可以写positions{n},例如:

>> positions{1}
ans =
    10     1
     2     3
     5     3
     3     4
     5     4
     1     5
     4     5
     .     .
     .     .
     .     .

仅行

如果您想要在每个给定行的列索引和n 中包含所有内容,您可以这样写:

A = randi(4,10,30);
row_pos = @(k,n) A(k,:)==n;
positions = false(size(A,1),max(A(:)),size(A,2));
for n = 1:max(A(:))
    positions(:,n,:) = row_pos(1:size(A,1),n);
end

现在,positions 是一个逻辑 3-D 数组,每一行对应A 中的一行,每一列对应一个值n,第三维是组合的存在向量行和n。这样,我们可以将R定义为列索引:

R = 1:size(A,2);

然后找到给定行和n 的相关位置。例如,第 9 行 n=3 的列索引为:

>> R(positions(9,3,:))
ans =
     2     6    18    19    23    24    26    27

这就像调用find(A(9,:)==3),但如果您需要多次执行此操作,查找所有索引并将它们存储在positions(这是合乎逻辑的,所以它不是那么大)会更快。

【讨论】:

    【解决方案2】:

    在矩阵中查找线性索引:I = find(A == 1)
    求矩阵 A 中的二维索引:[row, col] = find(A == 1)

    %Create sample matrix, with elements equal one:
    A = zeros(5, 4);
    A([2 10 14]) = 1
    
    A =
    
         0     0     0     0
         1     0     0     0
         0     0     0     0
         0     0     1     0
         0     1     0     0
    

    在 A 中查找线性索引:

    find(A == 1)
    
    ans =
    
         2
        10
        14
    
    %This is the same as reshaping A to a vector and find ones in the vector:
    B = A(:);
    find(B == 1);
    
    B' =
    
         0     1     0     0     0     0     0     0     0     1     0     0     0     1     0     0     0     0     0     0
    

    查找二维索引:

    [row, col] = find(A == 1)
    
    row =
    
         2
         5
         4
    
    
    col =
    
         1
         2
         3
    

    【讨论】:

      【解决方案3】:

      您可以通过accumarray 使用anonymous function 来执行此操作,如下所示:

      positions = accumarray(v(:), 1:numel(v), [], @(x) {sort(x.')});
      

      对于

      v = [ 1 3 3 3 4 2 1 2 3 4 3 2 1 4 3 3 4 2 2];
      

      这给了

      positions{1} =
           1     7    13
      positions{2} =
           6     8    12    18    19
      positions{3} =
           2     3     4     9    11    15    16
      positions{4} =
           5    10    14    17
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-03-02
        • 2021-02-10
        • 1970-01-01
        • 2017-12-05
        • 2013-11-06
        • 2019-03-02
        • 1970-01-01
        相关资源
        最近更新 更多