Arrays 在字符串数组中查找多个重复列并在MATLAB中合并它们
我有一个2列的字符数组单元格和一个相同长度的数字数组。如果两列都匹配,那么我希望通过删除它们并对数值数组行求和来合并这些行 例如,如果字符串的一行是Arrays 在字符串数组中查找多个重复列并在MATLAB中合并它们,arrays,string,matlab,loops,Arrays,String,Matlab,Loops,我有一个2列的字符数组单元格和一个相同长度的数字数组。如果两列都匹配,那么我希望通过删除它们并对数值数组行求和来合并这些行 例如,如果字符串的一行是{'abd','123'},而另一行是{'abd','123'},那么我需要所有这些索引,这样我就可以打印出一个包含3列的CSV文件,其中前2行是唯一的,第3行是重复项的总和 我正在使用Matlab2012 textdata = {'1','3','6','6','12','12','12','4','1'}'; textdata(:,2) = {'
{'abd','123'}
,而另一行是{'abd','123'}
,那么我需要所有这些索引,这样我就可以打印出一个包含3列的CSV文件,其中前2行是唯一的,第3行是重复项的总和
我正在使用Matlab2012
textdata = {'1','3','6','6','12','12','12','4','1'}';
textdata(:,2) = {'c','q','r','r','s','b','s','q','d'}';
nums = [1,4,5,6,7,3,2,23,34]';
这和我刚刚在csv文件中读到的内容类似,其中两列是字符字符串,比如“223455”和“23455x”,所以我只是想用更小的数据集进行复制。我用你的方法解决问题,但不是像你说的那样处理行
% At = table(A(:,1), A(:,2));
[At2,~,ID] = unique(textdata,'rows');
At2.Var3 = accumarray(ID, nums(:));
% writetable(At2, 'output.csv', 'WriteVariableNames', false);
一种解决方法是将字符串数组转换成一个表,在这个表上使用,这样我们就可以建立一个映射到每一行的ID,然后最终使用它来执行所需的求和。假设
A
包含字符串数组,而B
包含相同大小的数字数组
因此:
At = table(A(:,1), A(:,2));
[At2,~,ID] = unique(At);
At2.Var3 = accumarray(ID, B(:));
writetable(At2, 'output.csv', 'WriteVariableNames', false);
第一行代码将字符串数组转换为实际表,其中每一列都是字符串数组中的一列。然后,我们使用unique
的第三个输出将表中的每一行转换为唯一的整数ID,以便具有相同ID的行表示它们的行内容相等。unique
的第一个输出为我们提供了一个新表,它只包含表中唯一的行。然后,我们使用accumarray
将具有相同ID的所有行分组在一起,并使用B
访问这些ID提供的相应位置,然后将这些值相加。这是accumarray的默认行为。accumarray
的输出将具有与唯一表相同的行数,并且顺序是每个元素为我们提供共享一行中相同字符串对的行的总和。然后,我们向该表中添加一个新列,并将其写入名为output.CSV
的CSV文件。我忽略了列标题,在上面的代码中创建一个表
,提供了填充列标题,这可能不是您想要的
举个简单的例子,假设a
和B
是:
>> A = string({'abd', '123'; 'abd', '123'; 'abcc', '1234'; 'abdef', '34567'})
A =
4×2 string array
"abd" "123"
"abd" "123"
"abcc" "1234"
"abdef" "34567"
>> B = [3; 4; 6; -1]
B =
3
4
6
-1
运行上述代码可以得到下表:
>> At2
At2 =
Var1 Var2 Var3
_______ _______ ____
"abcc" "1234" 6
"abd" "123" 7
"abdef" "34567" -1
我们可以看到,每一行都给出了共享字符串数组中相同位置的所有数值的总和。该矩阵的前两行具有相同的字符串对,因此它们对应的值3和4被添加到7。您可以自己验证表的其余部分。一种解决方法是将字符串数组转换为一个表,在该表上使用,以便我们可以建立一个映射到每一行的ID,然后最终使用该ID执行所需的求和。假设
A
包含字符串数组,而B
包含相同大小的数字数组
因此:
At = table(A(:,1), A(:,2));
[At2,~,ID] = unique(At);
At2.Var3 = accumarray(ID, B(:));
writetable(At2, 'output.csv', 'WriteVariableNames', false);
第一行代码将字符串数组转换为实际表,其中每一列都是字符串数组中的一列。然后,我们使用unique
的第三个输出将表中的每一行转换为唯一的整数ID,以便具有相同ID的行表示它们的行内容相等。unique
的第一个输出为我们提供了一个新表,它只包含表中唯一的行。然后,我们使用accumarray
将具有相同ID的所有行分组在一起,并使用B
访问这些ID提供的相应位置,然后将这些值相加。这是accumarray的默认行为。accumarray
的输出将具有与唯一表相同的行数,并且顺序是每个元素为我们提供共享一行中相同字符串对的行的总和。然后,我们向该表中添加一个新列,并将其写入名为output.CSV
的CSV文件。我忽略了列标题,在上面的代码中创建一个表
,提供了填充列标题,这可能不是您想要的
举个简单的例子,假设a
和B
是:
>> A = string({'abd', '123'; 'abd', '123'; 'abcc', '1234'; 'abdef', '34567'})
A =
4×2 string array
"abd" "123"
"abd" "123"
"abcc" "1234"
"abdef" "34567"
>> B = [3; 4; 6; -1]
B =
3
4
6
-1
运行上述代码可以得到下表:
>> At2
At2 =
Var1 Var2 Var3
_______ _______ ____
"abcc" "1234" 6
"abd" "123" 7
"abdef" "34567" -1
我们可以看到,每一行都给出了共享字符串数组中相同位置的所有数值的总和。该矩阵的前两行具有相同的字符串对,因此它们对应的值3和4被添加到7。您可以自己验证表的其余部分。从您的示例中获取数据,让我们像这样设置它
myCell = {'1', '3', '6', '6', '12', '12', '12', '4', '1';
'c', 'q', 'r', 'r', 's', 'b', 's', 'q', 'd'}.';
nums = [1, 4, 5, 6, 7, 3, 2, 23, 34].';
所以我们想要合并'6',r'
行和'12',s'
行
现在,如果您的数据都是数字,我们可以使用unique(myData,'rows')
,但是单元格数组不支持'rows'
。我们可以调用unique
一次,重塑结果,然后在索引上再次调用unique
。因为索引是数字的,我们现在可以使用“行”
% Get unique strings, use stable so result isn't sorted
% To start with, we are only interested in the indices of duplicate items, didx
[~, ~, didx] = unique(myCell, 'stable');
% Reshape back to 2 columns and run unique on the rows
% This time we also save the indices of the unique rows, uidx
[~, uidx, didx] = unique(reshape(didx, [], 2), 'rows', 'stable');
现在,您可以使用accumarray
和一些连接来获得结果
result = [myCell(uidx, :), num2cell(accumarray(didx, nums))];
>> result =
{ '1' 'c' 1
'3' 'q' 4
'6' 'r' 11
'12' 's' 9
'12' 'b' 3
'4' 'q' 23
'1' 'd' 34 }
% Note how the '6','r' and '12','s' rows have values of 11=6+5 and 9=7+2 respectively
以您的示例中的数据为例,让我们这样设置它
myCell = {'1', '3', '6', '6', '12', '12', '12', '4', '1';
'c', 'q', 'r', 'r', 's', 'b', 's', 'q', 'd'}.';
nums = [1, 4, 5, 6, 7, 3, 2, 23, 34].';
所以我们想要合并'6',r'
行和'12',s'
行
现在,如果您的数据都是数字,我们可以使用unique(myData,'rows')
,但是单元格数组不支持'rows'
。我们可以调用unique
一次,重塑结果,然后在索引上再次调用unique
。因为索引是数字的,我们现在可以使用“行”
% Get unique strings, use stable so result isn't sorted
% To start with, we are only interested in the indices of duplicate items, didx
[~, ~, didx] = unique(myCell, 'stable');
% Reshape back to 2 columns and run unique on the rows
% This time we also save the indices of the unique rows, uidx
[~, uidx, didx] = unique(reshape(didx, [], 2), 'rows', 'stable');
现在您可以使用accumarray
和一些连接