Split vector into multiple vectors based on its content

I have a vector that I know will consist of the values ​​100, 200 and 400. The values ​​will not be jumbled, but let it be in order, for example

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

      

I want to split this vector into three vectors, each vector contains all values ​​of this type.

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

      

The target duration will change from time to time, as well as the proportion of 100, 200 and 400.

How can I make this split in a simple way?

My own solution looks like this, but I thought there was another way that requires less code.

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

      

+3


source to share


4 answers


Something simpler:

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

A = target(target==100)
B = target(target==200)
C = target(target==400)

      



How it works: target==x

Returns a boolean array of size equal to target

. Then you can use this boolean array for indexing target

.

+3


source


A slightly more general approach:

%// 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)

      

an alternative and probably faster approach:

%// 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})

      

I would personally recommend that you stop at this point and continue with the cell array!

If you know how many unique elements there are, and you really want to store them in separate variables, you can use:

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

      




The most common and error prone approach I could think of would be:

%// create a map container with all values you're expecting and it 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

      

You get a structure out

with fields A

, B

and C

:

The interesting part is that you can also automatically generate keySet

and valueSet

:

%// 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

      

This way you don't need to know what your elements are and how many different ones you have. The only difference from your original request is that you don't get the variables A

, B

and C

, a out.A

, out.B

andout.C

enter image description here

+3


source


Here's how to do it using diff

and find

.

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

as follows:

DiffVector =

  -Inf     0     0     0   100     0   200     0     0   Inf


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

      

indices

as follows:

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

      

Display the contents of a cell array

celldisp(v)

v{1} =

   100   100   100   100



v{2} =

   200   200



v{3} =

   400   400   400

      

You can combine the first 2 steps into one just for simplicity.

Yay!

+2


source


Another way is to sort and then cell by mat2cell

:

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

      

+1


source







All Articles