【问题标题】:MATLAB: After reshaping matrix to array, how can we know back where the value originally belongs to?MATLAB:将矩阵重塑为数组后,我们如何知道值最初属于哪里?
【发布时间】:2017-01-06 23:01:45
【问题描述】:

z = [1 3 5 6] 并通过获取每个元素之间的所有差异: 我们得到:

bsxfun(@minus, z', z)
ans =
     0    -2    -4    -5
     2     0    -2    -3
     4     2     0    -1
     5     3     1     0

我现在想按升序排列这些值并删除重复项。所以:

sort(reshape(bsxfun(@minus, z', z),1,16))
ans =
  Columns 1 through 13
    -5    -4    -3    -2    -2    -1     0     0     0     0     1     2     2
  Columns 14 through 16
     3     4     5


C = unique(sort(reshape(bsxfun(@minus, z', z),1,16)))
C =
    -5    -4    -3    -2    -1     0     1     2     3     4     5

但是通过查看[-5 -4 -3 -2 -1 0 1 2 3 4 5] 中的-5, 我怎么知道-5 来自哪里。通过阅读我自己的矩阵,

 0    -2    -4    -5
 2     0    -2    -3
 4     2     0    -1
 5     3     1     0

我知道它来自z(1) - z(4),即第 1 行第 4 列。

另外2 来自z(3) - z(2)z(2) - z(1),它们来自两种情况。不读取原始矩阵本身,我们怎么知道[-5 -4 -3 -2 -1 0 1 2 3 4 5]中的2原来在原始矩阵的第3行第2列和第2行第1列?

所以通过查看[-5 -4 -3 -2 -1 0 1 2 3 4 5] 中的每个元素,我们如何有效地知道-5 在原始矩阵索引中的位置。我想知道,因为我需要对 -5 和两个产生此结果的索引进行操作:例如,对于每个差异,比如说 -5,我做 (-5)*1*6,作为 z(1)- z(6) = -5。但是对于 2,我需要将 2*(3*2+2*1) 设置为 z(3) - z(2) = 2, z(2) - z(1) = 2,这并不明显。

仔细想想,我认为我不应该将bsxfun(@minus, z', z) 重塑为数组。我还将创建两个索引数组,以便我可以有效地执行上述(-5)*1*6 之类的操作。然而,这说起来容易做起来难,而且我还必须处理不明确的来源。还是我应该先做想要的操作?

【问题讨论】:

    标签: matlab


    【解决方案1】:

    使用unique 的第三个输出。并且不要排序,unique 会为您完成。

    [sortedOutput,~,linearIndices] = unique(reshape(bsxfun(@minus, z', z),[1 16]))
    

    您可以像这样从bsxfun 重构结果:

    distances = reshape(sortedOutput(linearIndices),[4 4]);
    

    如果你想知道某个值出现在哪里,你写

    targetValue = -5;
    targetValueIdx = find(sortedOutput==targetValue);
    linearIndexIntoDistances = find(targetValueIdx==linearIndices);
    [row,col] = ind2sub([4 4],linearIndexIntoDistances);
    

    因为linearIndicessortedOutput 中的第一个值出现在原始向量中的任何地方都是1。

    【讨论】:

    • 我得到了row = 1 col = 13 for targetValue = -5;
    • @kww:抱歉,我不知何故认为 z 是 4x4 数组。固定。
    【解决方案2】:

    如果将bsxfun 的结果保存在中间变量中:

    distances=bsxfun(@minus, z', z)
    

    然后您可以使用find 迭代地查找距离中C 的值。

    [rows,cols]=find(C(i)==distances)
    

    如果值重复,这将给出所有行和列。您只需将它们用于您的方程式。

    【讨论】:

      【解决方案3】:

      您可以使用accumarray 收集与差异矩阵中相同值对应的所有行和列索引:

      z = [1 3 5 6]; % data vector
      zd = bsxfun(@minus, z.', z); % matrix of differences
      [C, ~, ind] = unique(zd); % unique values and indices
      [rr, cc] = ndgrid(1:numel(z)); % template for row and col indices
      f = @(x){x}; % anonymous function to collect row and col indices
      row = accumarray(ind, rr(:), [], f); % group row indices according to ind
      col = accumarray(ind, cc(:), [], f); % same for col indices
      

      例如,C(6) 是值0,在zd 中出现四次,在row{6}col{6} 给定的位置:

      >> row{6}.'
      ans =
           3     2     1     4
      >> col{6}.'
      ans =
           3     2     1     4
      

      如您所见,不能保证结果是排序的。如果您需要按线性顺序对它们进行排序:

      rowcol = cellfun(@(r,c)sortrows([r c]), row, col, 'UniformOutput', false);
      

      现在

      >> rowcol{6}
      ans =
           1     1
           2     2
           3     3
           4     4
      

      【讨论】:

        【解决方案4】:

        我不确定我是否完全遵循,但有几点需要考虑:

        1. unique 默认会为你排序数据,所以你不需要先调用sort
        2. unique 实际上有三个输出,你可以使用第三个输出恢复你的原始向量(即重复)

          [C,~,ic] = unique(reshape(bsxfun(@minus, z', z),1,16))
          

          现在您可以拨打电话回到bsxfun(@minus, z', z),1,16)

          reshape(C(ic), numel(z), numel(z))
          
        3. 您可能对unique 的第二个输出更感兴趣,它告诉您每个唯一值在1-by-16 向量中的索引。这真的取决于你想要做什么。但是有了这个,你可以获得一个行列对列表来匹配你的唯一值:

          [rows, cols] = ndgrid(1:4);
          coords = [rows(:), cols(:)];
          [C, ia] = unique(reshape(bsxfun(@minus, z', z),1,16));
          coords_pairs = coords(ia,:)
          

          导致

          coords_pairs =
          
             1   4
             1   3
             2   4
             2   3
             3   4
             4   4
             4   3
             3   2
             4   2
             3   1
             4   1
          

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2023-01-25
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-03-19
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多