在matlab中读取不同大小的行的csv文件

read csv file in matlab with rows of different size

我要在 matlab 中读取一个大的 csv 文件,其中包含如下行:

1, 0, 1, 0, 1
1, 0, 1, 0, 1, 0, 1, 0, 1
1, 0, 1
1, 0, 1
1, 0, 1, 0, 1
0, 1, 0, 1, 0, 1, 0, 1, 0

为了读取大文件,我使用 textscan 但是我应该在文本文件的每一行中定义预期参数的数量。

使用 csvread 有帮助,但它太慢而且似乎效率不高。 是否有任何方法可以在每行中使用未知数量的输入 textscan ?或者对于这种情况你有什么其他的建议吗?

既然你说“用零填充的数值矩阵会很好”,有一个使用 textscan 的解决方案可以给你这个。然而,问题是您必须知道一行可以包含的最大元素数(即文件中最长的一行)。

如果您知道这一点,那么 textscan 的附加参数的组合允许您阅读不完整的行:

如果设置参数'EndOfLine','\r\n',文档说明:

If there are missing values and an end-of-line sequence at the end of the last line in a file, then textscan returns empty values for those fields. This ensures that individual cells in output cell array, C, are the same size.

因此,将问题中的示例数据保存为 differentRows.txt,以下代码:

% be sure about this, better to overestimate than underestimate
maxNumberOfElementPerLine = 10 ;

% build a reading format which can accomodate the longest line
readFormat = repmat('%f',1,maxNumberOfElementPerLine) ;

fidcsv = fopen('differentRows.txt','r') ;

M = textscan( fidcsv , readFormat , Inf ,...
    'delimiter',',',...
    'EndOfLine','\r\n',...
    'CollectOutput',true) ;

fclose(fidcsv) ;
M = cell2mat(M) ; % convert to numerical matrix

将return:

>> M
M =
     1     0     1     0     1   NaN   NaN   NaN   NaN   NaN
     1     0     1     0     1     0     1     0     1   NaN
     1     0     1   NaN   NaN   NaN   NaN   NaN   NaN   NaN
     1     0     1   NaN   NaN   NaN   NaN   NaN   NaN   NaN
     1     0     1     0     1   NaN   NaN   NaN   NaN   NaN
     0     1     0     1     0     1     0     1     0   NaN

作为替代方案,如果它产生显着的速度差异,您可以将数据导入整数而不是双精度。问题是 NaN 没有为整数定义,所以你有 2 个选择:

  • 1) 将 条目保留为默认值 0

只需将定义格式说明符的行替换为:

% build a reading format which can accomodate the longest line
readFormat = repmat('%d',1,maxNumberOfElementPerLine) ;

这将 return:

>> M
M =
1   0   1   0   1   0   0   0   0   0
1   0   1   0   1   0   1   0   1   0
1   0   1   0   0   0   0   0   0   0
1   0   1   0   0   0   0   0   0   0
1   0   1   0   1   0   0   0   0   0
0   1   0   1   0   1   0   1   0   0

  • 2) 用占位符替换 条目(例如:99

定义一个你确定你的原始数据中永远不会有的值(用于快速识别空单元格),然后使用 textscan 函数的 EmptyValue 参数:

readFormat = repmat('%d',1,maxNumberOfElementPerLine) ;
DefaultEmptyValue = 99 ; % placeholder for "empty values"

fidcsv = fopen('differentRows.txt','r') ;
M = textscan( fidcsv , readFormat , Inf ,...
    'delimiter',',',...
    'EndOfLine','\r\n',...
    'CollectOutput',true,...
    'EmptyValue',DefaultEmptyValue) ;

将产生:

>> M
M =
1   0   1   0   1   99  99  99  99  99
1   0   1   0   1   0   1   0   1   99
1   0   1   99  99  99  99  99  99  99
1   0   1   99  99  99  99  99  99  99
1   0   1   0   1   99  99  99  99  99
0   1   0   1   0   1   0   1   0   99