有没有办法在MATLAB中执行条件文本导入?例如使用以此格式的制表符分隔的.txt文件:
Type A B C D E
A 5000 2 5 16 19
A 5000 3 4 5 4
A 5000 4 1 4 5
B 500 19 8 2 7
B 500 18 9 8 1
B 500 2 9 13 2
B 100 3 10 15 9
B 5000 4 15 14 10
是否有方法只导入列A包含'5000'的那些行?
这优先于导入整个.txt文件并在之后分离数据,因为实际上,我的文本文件相当大(每个大约200MB) - 但如果有办法快速完成,那么这也是一个合适的解决方
或者,是否有一种方法(类似于R),您可以使用.txt文件中包含的标头导入和处理数据?例如导入'Type''A''B'和'D',而在上例中忽略'C'和'E'。如果输入文件格式灵活,并且添加了其他列,有时意味着它们的相对位置发生变化,则需要这样做。
答案 0 :(得分:1)
您可以尝试逐行读取输入文件,检查该行是否包含参考列中的参考值(本例中为5000)(在本例中为第2列)。
如果是这样,您可以存储输入,否则,您将其丢弃。
在以下代码中,您可以根据模板在代码的开头定义参考值和参考列。
然后,您可以将cellarray
输出转换为array
% Define the column index
col_idx=2
% Define the reference value
ref_value=5000
% Open input file
fid=fopen('in.txt');
% Read header
tline = fgetl(fid);
% Initialize conter
cnt=0;
% Initialize output variable
data=[];
% Read the file line by line
while 1
% Read the line
tline = fgetl(fid);
% Check for the end of file
if ~ischar(tline)
break
end
% Get the line field
c=textscan(tline,'%c%f%f%f%f%f')
% If the seconf field contains the ref value, then store the inout data
if(c{col_idx} == ref_value)
data=[data;c]
end
end
fclose(fid);
% Convert cell 2 array
c=data(:,2:end)
num_data=cell2mat(c)
% Convert first column to char
lab=char(data(:,1))
希望这有帮助。
答案 1 :(得分:0)
函数fgetl
用于从文本文件中读取单行,因此一个选项是编写一个循环,使用fgetl
连续读取一行并检查第一列是否包含" 5000"在决定是否将其包含在您的数据集中之前。
这是il_raffa答案中提出的解决方案。请注意,您实际上必须阅读整个文件,因为您使用fgetl
阅读整行,然后使用textscan
!所以它肯定不会比读取整个文件然后过滤它更快(尽管它可能更节省内存)。
你真正想要的是逐个字符地阅读文件,如果你可以根据" A"的价值确定你不会阅读它,就会中止每一行。列。
如果你正在编写C或其他低级语言,这可能比导入整个文件并在之后过滤它更快。但是,由于MATLAB引入的开销,几乎可以肯定更快更容易读取整个文件并在以后过滤它。 textscan
函数在读取分隔文件方面非常好(而且速度快),200MB实际上并不那么大(例如,它可以很舒适地放入任何现代计算机的内存中)。您应该确保在读取后过滤每个数据集,而不是读取所有数据集然后将它们全部过滤。
关于您是否可以有选择地导入列,问题的第二部分 - MATLAB没有提供内置的方法来执行此操作。但是,如果您可以对文件格式做一些假设,那就不是那么棘手了。如果我们假设
然后你可以阅读标题行(使用fgetl
),它会告诉你有多少列,以及它们的名称。然后,您可以使用该信息构建对textscan
的调用,该调用将读取分隔的列,并过滤掉其标题不符合您需要的列。这个的简单版本可能看起来像 -
function columns = import_columns(filename, headers)
fid = fopen(filename);
hdr = fgetl(fid);
column_headers = regexp(hdr, '\t', 'split'); % split on tabs
num_cols = length(column_headers);
format_str = repmat('%s', 1, num_cols); % create a string like '%s%s%s%s'
columns = textscan(fid, format_str, 'Delimiter', '\t');
fclose(fid);
required_cols = ismember(column_headers, headers);
columns(~required_cols) = []; % remove the columns you don't need
end