我实际上有一个包含uint8数据的文本文件,如下所示:
[0, 18, 121] bl
[0, 19, 12] gt
[24, 19, 22] apa
[0, 18, 1] bl
[24, 19, 22] apa bpa
[1, 2, 3] apa
我最终想要的是一个结构,比如A
,其中包含以下数据的字段为:
A.bl= [0, 18, 121;
0, 18, 1 ];
A.gt = [0, 19, 12];
A.apa = [24,19,22];
A.apa_bpa = [24,19, 22] or A.apabpa= [24, 19, 22]
所以上面的例子显示的是找到矩阵的多个实例并将它们堆叠成一个。如果名称中有空格,请删除该空格或用下划线替换它。
到现在为止,我有:
A = importdata('file.txt');
创建包含数据的单元格数组(我的原始数据为20,000 x 1)。我知道文本文件将具有的矩阵的名称。所以我试着区分下面的矩阵,它给出了包含矩阵的单元格及其名称:
A(~cellfun(@isempty, strfind(A,'bl')))
我该怎么办?或者以更快的速度解决这个问题的更简单方法是什么?
答案 0 :(得分:4)
在这种情况下,我会使用textscan
而不是importdata
,因为您正在处理混合数据类型:
fid = fopen('file.txt');
data = textscan(fid, '[%d%d%d%s', 'Delimiter', ',]', 'CollectOutput', true);
fclose(fid);
values = data{1};
fields = data{2};
这会在values
和fields
中为您提供以下结果:
values =
6×3 int32 matrix
0 18 121
0 19 12
24 19 22
0 18 1
24 19 22
1 2 3
fields =
6×1 cell array
'bl'
'gt'
'apa'
'bl'
'apa bpa'
'apa'
现在,您可以使用strrep
用下划线替换fields
中的空格,找到unique
的唯一字符串,使用accumarray
获取每个字符串的重复次数,{ {3}} values
行匹配唯一字段名称列表,并values
使用sort对行进行分组:
[fields, ~, index] = unique(strrep(fields, ' ', '_'));
counts = accumarray(index, 1);
[~, sortIndex] = sort(index);
values = mat2cell(values(sortIndex, :), counts);
现在,您可以使用mat2cell
轻松将所有内容整合到一个结构中:
S = cell2struct(values, fields)
S =
struct with fields:
apa: [2×3 int32]
apa_bpa: [24 19 22]
bl: [2×3 int32]
gt: [0 19 12]
答案 1 :(得分:1)
如果您的文件相当长,格式正确,并且您不想在eval中使用可怕的内容,我建议您使用旧版设置结构字段通过setfield
% I just copied data from top of the post to the document
fid = fopen('testdoc.txt');
store_struct = struct();
while ~feof(fid)
tmp_line = fgetl(fid);
delim_idx = find(tmp_line == ']');
tmp_mat=uint8(str2num(tmp_line(2:delim_idx-1)));
tmp_field = deblank(tmp_line(delim_idx+2:length(tmp_line)));
tmp_field(tmp_field == ' ') = '_';
if isfield(store_struct,tmp_field)
store_struct = setfield(store_struct,tmp_field,...
[getfield(store_struct,tmp_field);tmp_mat]);
else
store_struct = setfield(store_struct,tmp_field,...
tmp_mat);
end
end
fclose(fid);
答案 2 :(得分:1)
您可以使用textscan
作为gnovice建议读取数据
fid = fopen('file.txt');
data = textscan(fid, '[%d%d%d%s', 'Delimiter', ',]', 'CollectOutput', true);
fclose(fid);
values = data{1};
fields = data{2};
然后使用一个简单的循环来创建结构,因为你可以使用圆括号通过字符串访问结构的字段
% demo for accessing fields
myStruct.myField
% is equivalent to
myStruct.('myField')
所以:
% Replace spaces with underscores in 'fields'
fields = strrep(fields, ' ', '_');
% Initialise struct
A = struct;
% Loop over fields, assign values
for ii = 1:numel(fields)
if isfield(A,fields{ii})
% Append to array if field already exists
A.(fields{ii}) = [A.(fields{ii}); values(ii,:)];
else
% Create field as array if doesn't yet exist
A.(fields{ii}) = values(ii,:);
end
end