Matlab:找到向量中元素的第一次和最后一次出现?

Matlab: find first and final occurrences of elements in a vector?

我面临着一个不太容易处理的任务。

我有一个包含 4 个一、3 个二、2 个三和 4 个四的矢量图像:

 [1,1,1,1,2,2,2,3,3,4,4,4,4]

这意味着我有 1、2、3、4 出现次数不同。

我想找到这些元素的第一个位置和这些元素的最终位置。这意味着我想要:

更重要的是,如果参考向量是随机排序而不是排序怎么办?

我知道如何在 unique() 函数的帮助下使用 for 循环来完成它。

我正在寻找针对此类问题的更高效的矢量化解决方案

感谢您抽出宝贵时间,我们将不胜感激您的帮助。

查看以下代码和示例以及 this 答案:

a = [1,1,1,1,2,2,2,3,3,4,4,4,4];
first_occurences = [1, find(diff([a(1) a a(end)]))]
last_occurences = [first_occurences(2:end) - 1, length(a)]

 first_occurences =

     1     5     8    10


last_occurences =

     4     7     9    13

a = [2,2,2, 1,1,1,1,4,4,4,4, 3,3];
first_occurences = [1, find(diff([a(1) a a(end)]))]
last_occurences = [first_occurences(2:end) - 1, length(a)]


first_occurences =

     1     4     8    12


last_occurences =

     3     7    11    13


a = [4,4,4,4, 1,1,1,1, 3,3, 2,2,2];
first_occurences = [1, find(diff([a(1) a a(end)]))]
last_occurences = [first_occurences(2:end) - 1, length(a)]


first_occurences =

     1     5     9    11


last_occurences =

     4     8    10    13

我不确定为什么你不能在没有 for 循环的情况下使用 unique。仅使用第二个输出,您就可以确定要查找的内容。

以你的例子为例:

A = [1,1,1,1,2,2,2,3,3,4,4,4,4];

如果您想要 A 中每个唯一元素第一次出现的索引,只需这样调用 unique:

[~,out_first,~] = unique(A, 'first');

此外,如果您想为 A 中的每个唯一元素查找最后一次出现的索引,请这样做:

[~,out_last,~] = unique(A, 'last');

根据你上面的例子,这是我们第一次和最后一次出现的结果:

>> out_first

out_first =

     1
     5
     8
    10

>> out_last

out_last =

     4
     7
     9
    13

如果您的矢量 A 是随机顺序,unique 仍会找到相对于 A 起始位置的第一个匹配项。例如,如果我打乱 A:

中的元素
B = A(randperm(numel(A)))

>> B

B =

     2     1     4     2     3     2     1     1     1     4     3     4     4

这是我在 运行 unique 上对这个打乱的向量进行处理时得到的结果:

>> out_first

out_first =

     2
     1
     5
     3

>> out_last

out_last =

     9
     6
    11
    13

如您所见,我们第一次遇到值 1 时,它在索引 2 处,我们第一次遇到值 2 时,它在索引 1 处,依此类推。您可以按照上次遇到的相同模式。


因此,除了对 unique 的单个函数调用之外,我看不出你还能得到多少矢量化。无需使用 for 循环。

x = [1,1,1,1,2,2,2,3,3,4,4,4,4];
s = [1,2,3,4];
[valid, first] = max(bsxfun(@eq, x(:), s(:).'),[],1);
[~, last] = max(bsxfun(@eq, flipud(x(:)), s(:).'),[],1);
first(~valid) = 0;
last = numel(x)-last+1;
last(~valid) = 0;

这利用了这样一个事实,即 max returns 的第二个输出是每个列中 第一个 最大化器的位置。此外,第一个输出用于确保每个值至少出现一次;如果不是这种情况,则结果将设置为零。因此,例如 s = [1,2,3,4,5] 的结果将是

first =
     1     5     8    10     0
last =
     4     7     9    13     0

要获得 last 个位置,使用相同的方法,只是使用翻转向量。

每个向量中的元素可以按任意顺序排列。