MATLAB - 避免在元胞数组内的向量中重复值并取 next

MATLAB - Avoid repeated values in a vector inside cell arrays and take next

这是问题所在:

我有一个形式为 indx{ii} 的元胞数组,其中每个 ii 是一个大小为 1xNii 的数组(这意味着数组具有不同的大小)。 indy{jj} 形式的另一个元胞数组,其中每个 jj 都是与 ii.

大小相同的数组

问题是我想创建一个函数来评估 indx{:} 数组中的值并取第一个不重复的值,如果是重复值则取下一个值。

我会试着用一个例子来解释。假设我们有 indxindy 是元胞数组:

indx{1} = [1 3 2 7];
indx{2} = [3 8 5];
indx{3} = [3 6 2 9];
indx{4} = [1 3 4];
indx{5} = [3 1 4];

indy{1} = [0.12 0.21 0.31 0.44];
indy{2} = [0.22 0.34 0.54];
indy{3} = [0.13 0.23 0.36 0.41];
indy{4} = [0.12 0.16 0.22];
indy{5} = [0.14 0.19 0.26]; 

我想让代码做的是取第一个值并且在 indx 中不重复,在 indy 中不重复。所以这个例子的答案应该是:

ans=

indx{1} = 1;
indx{2} = 3;
indx{3} = 6;
indx{4} = 4;
indx{5} = [];

indy{1} = 0.12;
indy{2} = 0.22;
indy{3} = 0.23;
indy{4} = 0.22;
indy{5} = [];

ans 中,对于 indx{1},代码采用 1,因为它是第一个并且不会重复,并且在 indy 中采用等效值。然后对于 indx{2} 它需要 3 因为它是第一个值并且在之前的任何数组中都不会作为第一个值重复。但是对于 ind{3} 它需要 6,因为第一个值 3 重复了,并且在 indy 中取 6 的等效值 0.23。对于 ind{4},第一个和第二个值已作为第一个值重复,因此代码采用 4 及其在 indy 中的等价物。最后,对于 indx{5},因为所有值都已经重复,代码应该没有值。

indx{1} = [1 3 2 7];
indx{2} = [3 8 5];
indx{3} = [3 6 2 9];
indx{4} = [1 3 4];
indx{5} = [3 1 4];

indy{1} = [0.12 0.21 0.31 0.44];
indy{2} = [0.22 0.34 0.54];
indy{3} = [0.13 0.23 0.36 0.41];
indy{4} = [0.12 0.16 0.22];
indy{5} = [0.14 0.19 0.26]; 

indx2 = NaN(numel(indx),1);
indx2(1) = indx{1}(1);
indy2 = NaN(numel(indy),1);
indy2(1) = indy{1}(1);
for ii = 2:numel(indx)
    tmp1 = indx{ii}'; % get the original as array
    tmp2 = indy{ii}';
    if numel(tmp1)>numel(indx2)
        tmp3 = [indx2;NaN(numel(tmp1)-numel(indx2),1)];
        tmp4 = [indx2;NaN(numel(tmp1)-numel(indx2),1)];
    else
        tmp1 = [tmp1;NaN(numel(indx2)-numel(tmp1),1)];
        tmp2 = [tmp2;NaN(numel(indx2)-numel(tmp2),1)];
        tmp3 = indx2;
        tmp4 = indy2;
    end
    tmp5 = ~ismember(tmp1,tmp3); % find first non equal one
    tmp6 = find(tmp5,1,'first');
    indx2(ii) = tmp1(tmp6); % save values
    indy2(ii) = tmp2(tmp6);
end
N = numel(indx2);
indx2 = mat2cell(indx2, repmat(1,N,1));
N = numel(indy2);
indy2 = mat2cell(indy2, repmat(1,N,1));

indx2 =

    [  1]
    [  3]
    [  6]
    [  4]
    [NaN]

我在这里所做的是首先将输出单元格初始化为与原始数据具有相同数量的单元格。然后我分配值 1,因为它始终是唯一的,它是第一个条目。之后,我使用 for 循环首先将所有四个元胞数组(2 个输入,两个输出)转换为常规数组以进行处理,并使用 ismember, where I check for the all non-equal number between the next input cell and the existing numbers in your output. Then find 获取第一个不匹配的数字。最后,如果存在,则将数字分配给数组。

作为对 NaN 布尔值用法的评论,请尝试 NaN ~=NaNNaN ==NaN。第一个会给你 1,而第二个会给你零。这种品质使 NaN 成为此处填充的理想选择,因为 0 == 0 将导致 1:

A = [1,2,5,4,NaN];
B = [1,3,7,NaN,NaN];
ismember(A,B)
=

     1     0     0     0     0

因此 NaN 彼此不相等,因此不会污染您的解决方案。