Matlab从文本文件到稀疏矩阵。

时间:2017-05-15 20:21:49

标签: matlab file-io text-files sparse-matrix

我有一个大文本文件,格式如下:

1   2
1   3
1   10
1   11
1   20
1   376
1   665255
2   4
2   126
2   134
2   242
2   247

第一列是x坐标,第二列是y坐标。 它表明如果我必须构建一个矩阵

M = zeros(N, N);
M(1, 2) = 1;
M(1, 3) = 1;
.
.
M(2, 247) = 1;

此文本文件很大,无法立即进入主内存。我必须逐行阅读。并将其保存在稀疏矩阵

所以我需要以下功能:

function mat = generate( path )
    fid = fopen(path);
    tline = fgetl(fid);
    % initialize an empty sparse matrix. (I know I assigned Mat(1, 1) = 1)
    mat = sparse(1);
    while ischar(tline)
        tline = fgetl(fid);
        if ischar(tline)
            C = strsplit(tline);
        end
        mat(C{1}, C{2}) = 1;
    end
    fclose(fid);
end

但不幸的是,除了第一排之外,它只是把垃圾放在我的稀疏垫子里。 演示:

1 7
1 9
2 4
2 9

如果我打印稀疏垫,我得到:

   (1,1)        1
  (50,52)       1
  (49,57)       1
  (50,57)       1

有什么建议吗?

1 个答案:

答案 0 :(得分:3)

修复你拥有的......

您的问题是C是一个单元格数组of characters,而不是数字。您需要将从文件中读取的字符串转换为整数值。您可以使用strsplitstr2num等功能代替str2double。由于tline在这种情况下是以空格分隔的整数字符数组,因此str2num最容易用来计算C

C = str2num(tline);

然后你只需要像数组一样索引C而不是单元格数组:

mat(C(1), C(2)) = 1;

额外花絮:如果您想知道即使C包含字符,您的演示代码仍然有效,那是因为MATLAB有自动将变量自动转换为正确的倾向键入某些操作。在这种情况下,字符被转换为等同的double ASCII码:'1'变为49'2'变为50等等。然后它将这些用作索引到mat


更简单的替代方案......

您甚至不必为上述所有混乱而烦恼,因为您可以使用dlmreadsparse更简单的方法替换您的整个功能,如下所示:

data = dlmread(filePath);
mat = sparse(data(:, 1), data(:, 2), 1);
clear data;  % Save yourself some memory if you don't need it any more