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

Matlab from text file to 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 坐标。 这表明如果我必须构造一个 Matrix

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

有什么建议吗?

正在修复您所拥有的...

您的问题是 C 是元胞数组 of characters, not numbers. You need to convert the strings you read from the file into integer values. Instead of strsplit you can use functions like str2num and str2double。由于 tline 在这种情况下是一个 space 分隔的整数字符数组,因此 str2num 最容易用于计算 C:

C = str2num(tline);

那么你只需索引 C 就像一个数组而不是元胞数组:

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

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


更简单的选择...

您甚至不必为上面的所有混乱而烦恼,因为您可以使用 dlmread and sparse 以更简单的方法替换整个函数,如下所示:

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