如何从 txt 文件中读取特定的单词和数字并将它们保存在矩阵中

Posted

技术标签:

【中文标题】如何从 txt 文件中读取特定的单词和数字并将它们保存在矩阵中【英文标题】:How to read specific words and numbers from a txt file and save them in a matrix 【发布时间】:2014-10-18 12:47:03 【问题描述】:

我正在做对象检测,并希望从 7481 个文本文件中生成一个真实的 .mat 文件。这些文件的内容都是这样的格式:

car 0.00 0 -1.82 804.97 167.34 995.43 327.94 1.63 1.48 2.37 3.23 1.59 8.55 -1.47   
misc 0.00 5 2.35 254.24 -2 305.25 7.6 4.58 5.35 2.35 1.35 2.35 3.36 1.56  
bicycle 0.00 1 2 3 1 2.3 4.25 3.1 2 1 2.4 1.25 46.5 1.54  
don't know 0.00 2.21 5.32 1.23 5.25 9.46 4.35 1.25 5 1 3 2 4 1.54

即,在每个文本文件中,有几行(不同文件中的行数不同),并且在每一行中,第一项是类型(car/misc/people/van/don't know. ...),类型后面是 14 个由空格分隔符分隔的双精度数。我想做以下事情:

    检查类型是否为car/van/misc/tram 如果类型是其中之一,则在以下14个数字中,分别取第4、5、6、7、14个数字,然后存入一个矩阵中 对文件夹中的所有文本文件重复 1 和 2,然后生成包含地面实况信息的 mat 文件

现在我的代码是这样的:

clc;
clear all;
DetDir = '/scratch/yangj/project/car_dataset/training/label/';
F = dir([DetDir,'/*.txt']);
for frameNum = 1:7481

detFile = [DetDir,F(frameNum).name]; 

fid = fopen(detFile);

while 1
tline = fgetl(fid);
if ~ischar(tline), break, end
str = tline;

end
fclose (fid);

end

我认为我应该在 while 循环中进行类型检查和取数,但我不知道如何编写代码来实现我的目标。

你能帮我解决这个问题吗?

【问题讨论】:

【参考方案1】:

如果你的分隔符是一个空格,don't know 语句很烦人。我建议首先使用这个漂亮的 (Perl) 函数 replaceinfile 来解决这个问题,它可以将 don't know 更改为例如don't_know.

如果解决了,以下应该可以工作:

N = numel(F);
C = cell(N,1);
for idx = 1:N

    % get the data
    fid = fopen([DetDir F(idx).name]);
    data = textscan(fid,'%s %f %f %f %f %f %f %f %f %f %f %f %f %f %f');
    fclose(fid);

    % combine all numeric data 
    M = horzcat(data2:end);

    % check for a string match
    b = cellfun(@(type) strcmp(data1, type), 'car','van','misc','tram', 'uni', 0);

    % keep only the interesting part of the numeric data
    Cidx = M(any(horzcat(b:),2),[4 5 6 7 14]);
end

% combine and save
gt = vertcat(C:);
save('gt.mat', 'gt');

如果您不更改文件中的don't know 语句,代码实际上仍会运行,但(通常)不会产生所需的gt 矩阵。


要回答有关添加其他内容的问题:

在构造M之后,只需添加:

M(:,end+1) = M(:,6)-M(:,4); % this becomes the 15-th value

通过将Cidx = M(any(horzcat(b:),2),[4 5 6 7 14]); 更改为包含文件号来完成

fnr = (idx-1) * ones(sum(sum(horzcat(b:),2)),1);
Cidx = [fnr M(any(horzcat(b:),2),[4 5 7 14 15])];

【讨论】:

非常感谢您的回答...我犯了一个错误,'不知道'实际上是'DontCare',所以空间问题现在不是问题..但是,运行代码后,导出的 gt.mat 为空……不知道为什么会这样……而且,顺便说一下,如果我想将 frameNum 保存在矩阵的第一列(但请注意frameNum 是从 0000 到 7480),如果我想保存 a = 6th_Number - 4th_Number 来代替 6th_Number,我该怎么办? 嗯,这很有趣。在这里它工作正常。我建议调试代码并研究中间结果。首先从单个文件开始并研究data 单元格数组:它是否包含所需的数据?接下来,考虑字符串匹配:b 元胞数组是否如您所愿? (此数组中的第一个单元格包含一个匹配单词car 的数组,第二个匹配van,依此类推)。 我知道错误在哪里......因为它应该是'Car'而不是'car'......非常感谢......并且,你能帮我解决这个问题:如果我想在矩阵的第一列保存txt编号(但请注意,txt编号是从0000到7480),如果我想保存a = 6th_Number - 4th_Number来代替6th_Number,我应该怎么做做什么? 我在上次编辑中包含了一个答案。顺便说一句,使用strcmpi 比较字符串不区分大小写,因此您可以在代码中更改它。无论如何,如果现在一切都已解决 - 您可以考虑通过单击复选标记来接受此答案。谢谢! 是的,我点击了,非常感谢!你的回答真的很有帮助。

以上是关于如何从 txt 文件中读取特定的单词和数字并将它们保存在矩阵中的主要内容,如果未能解决你的问题,请参考以下文章

如何按整数读取文件整数并将它们放入二维数组?

如何有效地从大 txt 文件中读取字符串

从文件中读取字符串并使用 Groovy 将它们放入数组中

如何让 MS Access 以特定时间间隔从 .txt 文件中读取?

从文件中读取行并将它们分成两个数字并执行计算并将它们写入文件c ++

如果字符串和数字在同一行,是否可以读取它们(从TXT文件中)。