根据其内容将向量拆分成多个向量

3

我有一个向量,其中包含值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
4个回答

3

更简单的内容:

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

似乎所有的解决方案都很好,但我选择简单的解决方案!至少现在是这样。谢谢! - maxala

3
一个更加通用的方法:

稍微通俗易懂一些:

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

你将获得一个具有字段 ABC 的结构体 out
有趣的部分是,你也可以自动生成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

enter image description here


哈哈。喜欢这种替代方法...但是可读性有点差。这就是代码注释非常有意义的地方。 - Hoki

2
这里有一种使用 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

为了简化流程,您可以将前两个步骤合并为一个步骤。

耶!


1
另一种方法:使用mat2cell进行排序,然后拆分为单元格。
st = sort(target);
result = mat2cell(st, 1, diff([0 find(diff(st)) numel(st)]));

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接