【问题标题】:Skip lines based on condition MATLAB基于条件的跳行 MATLAB
【发布时间】:2015-11-02 20:10:51
【问题描述】:

在 MATLAB 中读取文本文件时,我使用:

file = fopen(filename, 'r');
formatSpec = '%d %d %d %d';
A = fscanf(file, formatSpec, [4 Inf]);

并非每一行都符合 formatSpec 并且可以包含错误消息。现在 Matlab 将停止在与上述格式不对应的行处。

如何跳过格式规范无法匹配的所有行?

所以输入文件看起来像这样:

04 2 1 312
04 2 2 212
04 error
05 2 1 421

应该给我以下矩阵:

 04  04  05
  2   2   2
  1   2   1
312 212 421

【问题讨论】:

  • 查看textscan命令而不是fscanf并尝试使用函数的'EmptyValue''TreatAsEmpty'参数。
  • 虽然不能真正回答您的问题,但请考虑使用grepawk 预处理您的输入文件。过去这对我来说效果很好 - 如果您的数据文件很大,那么在 MATBLAB 中处理输入文本可能会对性能产生重大影响(这可能对您的应用程序很重要,也可能不重要),因此只需确保所有数据一开始都是干净的。
  • 感谢您的回答,我将研究 textscan。由于我不太擅长使用 grep/awk,我希望在 Matlab 中做到这一点。

标签: matlab file scanf


【解决方案1】:

这应该适用于您的示例。 它读取一行,用空格分割它并检查所有元素是否都是整数(这可以更改为 double 或 else)。如果有一个字符串,则跳过该行,否则它将元素写入矩阵并用 NaN 填充其余部分。后者仅适用于每行元素数量不同的情况...... 只需确保 linemax 大于数据文件中的行数,并且 elementsmax 大于每行的元素数。

clear all
fclose all;
filename = 'text_test.dat';

file = fopen(filename, 'r');
linemax     = 1000;
elementsmax = 100;
A = zeros(linemax,elementsmax);
line = 1;
real_elementsmax = 1;
while (feof(file) == 0 && line < linemax)       % read until the end of the file is reached
    linetext = fgetl(file); %read frst line of the file
    text_array=regexp(linetext,' ','split');
    if min(isint(str2double(text_array)))
        nelements = size(text_array,2);
        A(line,1:nelements) = str2double(text_array(1:nelements));
        A(line,nelements+1:elementsmax) = NaN;
        line = line+1;
        real_elementsmax = max(real_elementsmax,nelements);
    end
end
fclose(file);
A(line:linemax,:)=[];
A(:,real_elementsmax+1:elementsmax)=[];

【讨论】:

  • 我之所以使用 fscanf 和 [4 Inf] 格式化参数是因为我无法提前知道文件的大小
  • @Lukas Häfliger,这应该不是我发布的代码的问题,因为我保持它的一般性。您可以将 elementsmax 设置为 10000,因为最终所有多余的线都将被消除,因此您拥有正确的形状。限制只是预分配所需的内存。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-01
  • 2012-05-29
相关资源
最近更新 更多