MATLAB:在将矩阵重新整形为数组之后,我们如何知道该值最初所属的位置?

时间:2016-08-26 08:23:53

标签: matlab

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中的[-5 -4 -3 -2 -1 0 1 2 3 4 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),来自两个案例。如果不阅读原始矩阵本身,我们如何知道2中的[-5 -4 -3 -2 -1 0 1 2 3 4 5]最初位于原始矩阵的第3行第2列和第2行第1列?

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

认真思考,我认为我不应该将z(2) - z(1) = 2重塑为数组。我还将创建两个索引数组,以便我可以有效地执行上述bsxfun(@minus, z', z)之类的操作。然而,这说起来容易做起来难,我也必须照顾不同的来源。或者我应该先做所需的操作吗?

4 个答案:

答案 0 :(得分:3)

使用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);

因为linearIndices中的sortedOutput中的第一个值出现在原始向量中,所以var destinations = {}; ... 为1。

答案 1 :(得分:2)

如果将distances=bsxfun(@minus, z', z) 的结果保存在中间变量中:

C

然后,您可以迭代地使用find在距离中查找[rows,cols]=find(C(i)==distances) 的值。

$data = DB::select("SELECT * FROM verified_data where target_id=3");

if ( !empty($data) && is_array($data) ) {
    foreach ( $data as $record ) {
        $record->is_verified; //TODO do something with this value
    }
}

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

答案 2 :(得分:1)

您可以使用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

答案 3 :(得分:0)

我不确定我是否完全遵循了一些要考虑的要点:

  1. sort会默认为您排序数据,因此您不需要先致电[C,~,ic] = unique(reshape(bsxfun(@minus, z', z),1,16))
  2. unique实际上有三个输出,您可以使用第三个输出恢复原始矢量(即重复),所以

    bsxfun(@minus, z', z),1,16)

    现在您可以通过致电

    返回reshape(C(ic), numel(z), numel(z))
    unique
  3. 您可能对1的第二个输出更感兴趣,它会告诉您16 - by - [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
    

    导致

    git add index.html