【问题标题】:Delete repeated values of different data types from cell array从元胞数组中删除不同数据类型的重复值
【发布时间】:2023-03-04 13:51:01
【问题描述】:

我有一个包含许多重复值的单元格数组列表,其中包括字符串、采样时间、饱和上限和下限。

例如:

MyValues={  'Lookc_at_the_stars'
            'Lookc_how_they_shine'
            'forc_you'
            'andm_everything_they_do'
            'Theym_were_all_yellow'
            'COLDPLAY_STOP'
            'COLDPLAY_PLAY'
            'COLDPLAY_PLAY'
            'COLDPLAY_PLAY'
            'COLDPLAY_BREAK'
            'COLDPLAY_BREAK'
            'Lookc_How_they_shinefor_you'
            'its_true'
            'COLDPLAY_STOP'
            'COLDPLAY_STOP'   }

我需要的输出是:

NewMyValues = { 'Lookc_at_the_stars'
                'Lookc_how_they_shine'
                'forc_you'
                'andm_everything_they_do'
                'Theym_were_all_yellow'
                'COLDPLAY_STOP'
                'COLDPLAY_PLAY'
                'COLDPLAY_BREAK'
                'Lookc_How_they_shinefor_you'
                'its_true'  }

由于我尝试使用函数unique,我无法获得输出,因为它给了我一个错误,说

“使用单元格/唯一的错误
输入 A 必须是字符串元胞数组。”

MyValues 由不同类型的数据类型值组成。

谁能给我一个解决方案或功能代码,我可以删除重复的值?

【问题讨论】:

  • 您使用的是哪个版本的 Matlab? unique(MyValues, 'stable') 在 Matlab 2015b 中工作。
  • 在您提供的示例中,只有字符串。如果您在编写时提供包含 字符串、采样时间、饱和上限和下限的示例,说明您的实际数据包含所有这些,那会更好。
  • 嗨@Jørgen我使用的是相同版本的Matlab 2015b,它给出了同样的错误
  • @MohammedNadaf 这是因为您的实际数据不仅仅包含字符串。如果您的数据仅包含字符串,Jørgen 的答案将起作用。您应该提供一个更好的数据示例,涵盖您提到的所有方面:字符串、采样时间、饱和上限和下限

标签: arrays matlab unique cell


【解决方案1】:

这是一个基于循环的解决方案,用于提取不同类型的元胞数组的唯一值:

MyValues={  'Lookc_at_the_stars',
            'Lookc_how_they_shine',
            1,
            'forc_you',
            'andm_everything_they_do',
            'Theym_were_all_yellow',
            2,
            'COLDPLAY_STOP',
            'COLDPLAY_PLAY',
            1,
            'COLDPLAY_PLAY',
            'COLDPLAY_PLAY',
            {1 2 3},
            'COLDPLAY_BREAK',
            {4 3 5},
            'COLDPLAY_BREAK',
            {1 2 3},
            'Lookc_How_they_shinefor_you',
            'its_true',
            'COLDPLAY_STOP',
            'COLDPLAY_STOP'   };
N = numel(MyValues);
idx = true(N,1);
for m = 1: N
    if idx(m)
        for n = (m+1):N
            if idx(n) && isequal(MyValues{m}, MyValues{n})
                idx(n) = false;
            end
        end
    end
end
result = MyValues(idx);

结果:

result =
{
  [1,1] = Lookc_at_the_stars
  [1,2] = Lookc_how_they_shine
  [1,3] =  1
  [1,4] = forc_you
  [1,5] = andm_everything_they_do
  [1,6] = Theym_were_all_yellow
  [1,7] =  2
  [1,8] = COLDPLAY_STOP
  [1,9] = COLDPLAY_PLAY
  [1,10] =
  {
    [1,1] =  1
    [1,2] =  2
    [1,3] =  3
  }
  [1,11] = COLDPLAY_BREAK
  [1,12] =
  {
    [1,1] =  4
    [1,2] =  3
    [1,3] =  5
  }
  [1,13] = Lookc_How_they_shinefor_you
  [1,14] = its_true
}

函数isequal 可以使用它来比较任何东西,所有的值都被比较并删除了重复项。所以result 是一个包含唯一值的元胞数组。
根据问题中的示例,如果您想拥有唯一的字符单元格数组,您可以使用 cellfun 和 ischar 来检查单元格值是否为字符数组。然后使用逻辑索引提取它们并应用unique。

unique(MyValues(cellfun(@ischar,MyValues)),'stable')

不使用stable 选项,结果将被排序

【讨论】:

  • 没有给出所需的顺序。
  • OP 的数据可以有采样时间、饱和上限和下限,如果它们是char 以外的任何类型,则此代码将忽略它们。他也想删除该数据的重复项。
  • 我从他的问题中复制粘贴了 OP 的话,写得很清楚。问题下的 cmets 中 OP 和 Jørgen 之间的对话也表明了这一点。 P.S 我不是这里的反对者
  • 我几乎认识神秘的反对者:)。如果是这样containers.Map 很有用。不幸的是octave没有这个容器你可以发布一个答案
  • 我对此不太熟悉。如果您有一些代码要检查但没有 MATLAB,我可以为您运行。我能提供的就这些
【解决方案2】:

您在问题中提供的单元格仅包含字符串,因此 unique 可以处理它。但是,如果您向其中添加整数、浮点数或复数,则可以在调用 unique 之前将所有单元格元素转换为字符串。比如我给你看一个小strcaster函数

function y = strcaster(x)
    if ischar(x)
        y = x;
    elseif isreal(x)
        y = num2str(x);
    else
        if imag(x)>=0
            s = '+j';
        else
            s = '-j';
        end
        y = [num2str(real(x)),s,num2str(imag(x))];
    end
end

然后您可以获取唯一元素,保留它们在单元格中出现的顺序,执行以下操作:

MyValues={'Lookc_at_the_stars',...
'Lookc_how_they_shine',...
'forc_you',...
'andm_everything_they_do',...
'Theym_were_all_yellow',...
'COLDPLAY_STOP',...
'COLDPLAY_PLAY',...
'COLDPLAY_PLAY',...
'COLDPLAY_PLAY',...
'COLDPLAY_BREAK',...
'COLDPLAY_BREAK',...
'Lookc_How_they_shinefor_you',...
'its_true',...
'COLDPLAY_STOP',...
'COLDPLAY_STOP',...
1,...
1.32423,...
complex(-3.,13)};
[u,i] = unique(cellfun(@(x)strcaster(x),MyValues,'uniformoutput',false),'stable');
disp(MyValues(i))

编辑

根据您的评论,很明显MyValues 单元格包含其他单元格,这在您的问题示例中并不清楚。在MyValues 中获取唯一值的最佳方法仍然是将内容转换为字符串。 JSON 协议将允许您将几乎任何数据类型转换为字符串,因此我建议通过以下方式使用 matlab 的jsonencode 函数:

MyValues={'Lookc_at_the_stars',...
'Lookc_how_they_shine',...
'forc_you',...
'andm_everything_they_do',...
'Theym_were_all_yellow',...
'COLDPLAY_STOP',...
'COLDPLAY_PLAY',...
'COLDPLAY_PLAY',...
'COLDPLAY_PLAY',...
'COLDPLAY_BREAK',...
'COLDPLAY_BREAK',...
'Lookc_How_they_shinefor_you',...
'its_true',...
'COLDPLAY_STOP',...
'COLDPLAY_STOP',...
1,...
1.32423,...
[1,23,4,4;5,3,2,1],...
{'bla',1324,{'12',123}},...
struct('NextTime','Provide a complete working example in the question')};
[u,i] = unique(cellfun(@(x)jsonencode(x),MyValues,'uniformoutput',false),'stable');
disp(MyValues(i))

【讨论】:

  • 嗨@lucianopaz,我在使用你的函数strcaster(x)时出错,它说:“未定义函数'imag'用于'cell'类型的输入参数。如果imag(x)在strcaster中出错)>=0 as>@(x)strcaster(x) 错误 as [u,i] = unique(cellfun(@(x)strcaster(x),ParameterValues,'uniformoutput',false),'stable' )"
  • 当然你得到一个错误。我写的 strcaster 函数不是用来处理结构、单元格或矩阵的。但是,这可以通过稍微改变它来使用 json 将任何内容转换为字符串来完成。如果你提供了一个完整的工作示例,显示你有单元格,我会从一开始就使用 json。
猜你喜欢
  • 2014-07-20
  • 2021-05-19
  • 1970-01-01
  • 2017-05-06
  • 1970-01-01
  • 2016-10-26
  • 1970-01-01
  • 2011-09-07
  • 1970-01-01
相关资源
最近更新 更多