在MATLAB中存储16×(2 ^ 20)矩阵的最佳方法是什么?

时间:2010-05-24 19:44:08

标签: matlab matrix file-io bigdata

我正在考虑将数据写入文件。有没有人有一个如何将大量数据写入文件的例子?

编辑:矩阵中的大多数元素都是零,其他元素是uint32。我想最简单的save()load()会起作用,就像@Jonas所说的那样。

3 个答案:

答案 0 :(得分:6)

我猜没有人看到关于零的编辑:)

如果它们大多是零,则应将矩阵转换为稀疏表示,然后然后保存它。您可以使用sparse函数执行此操作。

代码

z = zeros(10000,10000);
z(123,456) = 1;
whos z
z = sparse(z);
whos z

输出

Name          Size                   Bytes  Class     Attributes

  z         10000x10000            800000000  double  

Name          Size               Bytes  Class     Attributes

  z         10000x10000            40016  double    sparse    

我不认为稀疏实现旨在处理uint32

答案 1 :(得分:3)

如果您担心数据文件的大小尽可能小,可以参考以下建议:

  • 将数据写入二进制文件(即使用FWRITE)而不是文本文件(即使用FPRINTF)。
  • 如果您的数据包含所有整数值,请将其转换为signed or unsigned integer type或将其保存为double precision type,而不是默认的double precision type MATLAB使用。
  • 如果您的数据包含浮点值,但您不需要默认single precision type的范围或分辨率,请将其转换为FIND或将其另存为FREAD
  • 如果您的数据足够稀疏(即矩阵中的零多于零),则可以使用FWRITE函数获取非零值的行和列索引,然后将它们保存到您的文件中。

以下是几个例子来说明:

data = double(rand(16,2^20) <= 0.00001);  %# A large but very sparse matrix

%# Writing the values as type double:
fid = fopen('data_double.dat','w');  %# Open the file
fwrite(fid,size(data),'uint32');     %# Write the matrix size (2 values)
fwrite(fid,data,'double');           %# Write the data as type double
fclose(fid);                         %# Close the file

%# Writing the values as type uint8:
fid = fopen('data_uint8.dat','w');  %# Open the file
fwrite(fid,size(data),'uint32');    %# Write the matrix size (2 values)
fwrite(fid,data,'uint8');           %# Write the data as type uint8
fclose(fid);                        %# Close the file

%# Writing out only the non-zero values:
[rowIndex,columnIndex,values] = find(data);  %# Get the row and column indices
                                             %#   and the non-zero values
fid = fopen('data_sparse.dat','w');  %# Open the file
fwrite(fid,numel(values),'uint32');  %# Write the length of the vectors (1 value)
fwrite(fid,rowIndex,'uint32');       %# Write the row indices
fwrite(fid,columnIndex,'uint32');    %# Write the column indices
fwrite(fid,values,'uint8');          %# Write the non-zero values
fclose(fid);                         %# Close the file

上面创建的文件大小差别很大。文件'data_double.dat'大约为131,073 KB,'data_uint8.dat'大约为16,385 KB,'data_sparse.dat'小于2 KB。

请注意,我还将数据\ vector大小写入文件,以便可以回读数据(使用{{3}})并正确地重新整形。另请注意,如果我没有向{{3}}提供'double''uint8'参数,MATLAB将足够聪明,可以确定它不需要使用默认的双精度,并且只使用8位写出数据值(因为它们都是0和1)。

答案 2 :(得分:2)

如何生成数据?您如何访问数据?

如果我正确计算,如果变量全部加倍,则变量小于200MB。因此,如果您只需要从Matlab访问它,就可以轻松地将其保存并加载为单个.mat文件。

%# create data
data = zeros(16,2^20);

%# save data
save('myFile.mat','data');

%# clear data to test everything works
clear data

%# load data
load('myFile.mat')