【问题标题】:Split vector into several vectors depending on its content根据其内容将向量拆分为多个向量
【发布时间】:2015-06-18 15:30:15
【问题描述】:

我有一个向量,我知道它将由值 100、200 和 400 组成。这些值不会混淆,而是按顺序排列,例如

target = [100 100 100 100 200 200 400 400 400];

我想把这个向量分成三个向量,每个向量都包含所有那种类型的值。

A = [100 100 100 100];
B = [200 200];
C = [400 400 400];

目标的长度会不时变化,100、200和400的比例也会变化。

如何以简单的方式进行拆分?

我自己的解决方案看起来像这样,但我在想还有另一种方法需要更少的代码。

columns = size(target, 2);

A = [];
B = [];
C = [];
% Splitting target into groups
for j = 1:columns
    if target(1, j) == 100
        A = [A, 100];
    elseif target(1, j) == 200
        B = [B, 200];
    elseif target(1,j) == 400
        C = [C, 400];
    end
end

【问题讨论】:

    标签: arrays matlab vector


    【解决方案1】:

    更简单的:

    target=[100 100 100 100 200 200 400 400 400];
    
    A = target(target==100)
    B = target(target==200)
    C = target(target==400)
    

    这是如何工作的:target==x 返回一个大小等于target 的逻辑数组。然后您可以使用该逻辑数组来索引target

    【讨论】:

    • 似乎所有的解决方案都很好,但我会选择简单的解决方案!至少现在。谢谢!
    【解决方案2】:

    更通用的方法:

    %// find and count unique elements
    [a,b] = hist(target,unique(target));
    
    %// Create vectors according to target and number occurences and store them in cell array
    temp = arrayfun(@(x,y) y*ones(x,1),a,b,'uni',0)
    

    另一种可能更快的方法是:

    %// get indices of unique values
    [~,~,c] = unique(target)
    %// Create vectors according to indices and store them in cell array
    temp = accumarray(c(:),target(:),[],@(x) {x})
    

    我个人建议您在此停止并继续使用元胞数组!

    如果您知道有多少独特元素并且您真的想将它们存储在单独的变量中,您可以使用:

    [A,B,C] = temp{:}
    

    我能想到的最通用和最容易出错的方法是:

    %// create a map container with all values you're expecting and it's corresponding specifier
    valueSet =   {'A', 'B', 'C'};
    keySet = [100 200 400];
    mapObj = containers.Map(keySet,valueSet)
    
    %// create a struct and distribute keys to specifier
    for ii = 1:numel(keySet);
       out.(mapObj(keySet(ii))) = target(target == keySet(ii));
    end
    

    你会得到一个结构体out,其中包含ABC 字段:

    有趣的是,您还可以自动生成keySetvalueSet

    %// keySet are all unique values of target
    keySet = unique(target)
    %// create specifiers according to number of unique elements
    valueSet = cellstr(char(65:65+numel(keySet)-1).') %'
    %// you get 'A' 'B' and 'C' to use as field names
    

    这样您就不需要知道哪些是您的元素以及您实际拥有多少不同的元素。与原始请求的唯一区别是您没有获得变量 ABC,而是获得了 out.Aout.Bout.C

    【讨论】:

    • 哈哈。喜欢另一种方法……但可读性不好。这是评论代码很有意义。
    【解决方案3】:

    这是一种使用difffind 的方法。

    clear
    clc
    close all
    
    target=[100 100 100 100 200 200 400 400 400];
    
    %// Form vector containing cumulative differences from consecutive elements
    DiffVector = [-Inf diff([target Inf])];
    

    DiffVector 看起来像这样:

    DiffVector =
    
      -Inf     0     0     0   100     0   200     0     0   Inf
    
    
    %// Find where values are not equal to 0. That's the starting indices of
    %each sequence of numbers of interest.
    indices = find(DiffVector~=0)
    

    indices 看起来像这样:

    indices =
    
         1     5     7    10
    
    %// Put every sequence in its own cell.
    v = cell(1,numel(indices)-1);
    for k = 1:numel(indices)-1
        v{k} = target(indices(k):idx(k+1)-1);
    end
    

    显示元胞数组的内容

    celldisp(v)
    
    v{1} =
    
       100   100   100   100
    
    
    
    v{2} =
    
       200   200
    
    
    
    v{3} =
    
       400   400   400
    

    为简单起见,您可以将前 2 个步骤合并为一个。

    耶!

    【讨论】:

      【解决方案4】:

      还有一种方式:排序然后使用mat2cell分割成单元格:

      st = sort(target);
      result = mat2cell(st, 1, diff([0 find(diff(st)) numel(st)]));
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-01-09
        • 1970-01-01
        • 2018-08-09
        • 2020-06-01
        • 1970-01-01
        • 1970-01-01
        • 2020-12-23
        • 1970-01-01
        相关资源
        最近更新 更多