Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/matlab/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在MATLAB中使用unique()重构向量_Matlab_Unique_Sorting - Fatal编程技术网

在MATLAB中使用unique()重构向量

在MATLAB中使用unique()重构向量,matlab,unique,sorting,Matlab,Unique,Sorting,假设A是一个200项单元格数组,包含4个不同的字符串(每个字符串有50个重复)。 B是包含一些整数的200项向量 我正在使用[cellNos cellStartInd enumCells]=unique(A)并获取A中的哪个项等于唯一字符串之一(enumCells是一个包含整数1-4的数组,类似于枚举字符串) 我想使用此信息从B创建一个4x50值矩阵,以便每列都有特定唯一字符串的值。换句话说,我想将B重塑为一个矩阵,其中列根据a中的每个唯一字符串排列。如果我正确理解了您的问题,可以使用find函

假设
A
是一个200项单元格数组,包含4个不同的字符串(每个字符串有50个重复)。
B
是包含一些整数的200项向量

我正在使用
[cellNos cellStartInd enumCells]=unique(A)
并获取
A
中的哪个项等于唯一字符串之一(enumCells是一个包含整数1-4的数组,类似于枚举字符串)


我想使用此信息从
B
创建一个4x50值矩阵,以便每列都有特定唯一字符串的值。换句话说,我想将
B
重塑为一个矩阵,其中列根据
a

中的每个唯一字符串排列。如果我正确理解了您的问题,可以使用find函数完成此操作。

要创建矩阵,只需编写:

M(:,1) = B(find(enumCells==1));
M(:,2) = B(find(enumCells==2));
M(:,3) = B(find(enumCells==3));
M(:,4) = B(find(enumCells==4));
也许有一种更优雅的方法,但这应该行得通

编辑:您可以尝试使用“排序”来完成。排序函数可以将排序的排列作为输出。尝试:

[s perm] = sort(enumCells);
M = reshape(B(perm),50,4);

如果每个字符串的条目数相同,如果条目数不同,此方法将起作用。请参阅@gnovice solution

NumStrings = numel(CellNos);
M = zeros(size(B,1)/NumStrings,NumStrings);
for i = 1:NumStrings
    M(:,i) = B(strcmp(B,CellNos{i}));
end

此外,如果您提前知道唯一字符串是什么(即CellNos),这允许您跳过唯一调用,这相对比较昂贵。

假设您已经知道将有多少次重复,并且所有字符串都以相同的频率重复,您可以执行以下操作:

%# sort to find where the entries occur (remember: sort does stable sorting)
[~,sortIdx] = sort(enumCells);

%# preassign the output to 50-by-4 for easy linear indexing
newB = zeros(50,4);

%# fill in values from B: first the 50 ones, then the 50 2's etc
newB(:) = B(sortIdx);

%# transpose to get a 4-by-50 array
newB = newB';
或者,以更紧凑的方式(谢谢@Rich C)


对于一般情况,如果您有不同的字符串,并且每个字符串出现的次数不同,
M_i
,则
B
中的每个对应值集将具有不同的长度,您将无法将这些值集串联到一个数字数组中。您将不得不存储在
N
-元素中设置ets,您可以使用函数和:

在每个字符串出现相同次数的特定情况下,上述代码仍然可以正常工作,您可以选择将输出从单元格数组转换为所需的数字数组,如下所示:

associatedValues = [associatedValues{:}];

注意:由于不能保证保持其累计项目的相对顺序,因此
关联值的单元格中项目的顺序可能与向量
B
中项目的相对顺序不匹配。确保
B
中的原始相对顺序保持不变的一种方法是修改调用修订如下:

 associatedValues = accumarray(index(:),1:numel(B),[],@(x) {B(sort(x))});
或者,您可以对输入进行排序以获得相同的效果:

[index,sortIndex] = sort(index);
associatedValues = accumarray(index(:),B(sortIndex),[],@(x) {x});

谢谢,这应该适用于4个唯一的字符串。实际上,我想要的解决方案需要更少的硬编码和可伸缩性,因为实际问题不同(即更复杂)这是最好的解决方案,前提是您事先知道重复。您可以将最后3行折叠为:
newB=reformate(B(sortIdx),[50 4])
@Rich C:谢谢你的建议!要折叠最后一行,你的解决方案还需要一个额外的转置,顺便说一句,+1再次很好地使用了
accumarray
!在我有
排序
想法之前,我尝试过这个解决方案,但失败了。@Jonas:对于所有字符串出现相同次数的简单情况,你的sol这绝对是一条路要走
 associatedValues = accumarray(index(:),1:numel(B),[],@(x) {B(sort(x))});
[index,sortIndex] = sort(index);
associatedValues = accumarray(index(:),B(sortIndex),[],@(x) {x});