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

Posted

技术标签:

【中文标题】在 MATLAB 中存储 16 × (2^20) 矩阵的最佳方法是啥?【英文标题】:What is the best way to store a 16 × (2^20) matrix in MATLAB?在 MATLAB 中存储 16 × (2^20) 矩阵的最佳方法是什么? 【发布时间】:2010-05-24 19:44:08 【问题描述】:

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

编辑:矩阵中的大多数元素为零,其他元素为uint32。正如@Jonas 所建议的那样,我想最简单的save()load() 会起作用。

【问题讨论】:

【参考方案1】:

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

如果它们大多为零,则应将矩阵转换为其稀疏表示并然后保存它。您可以使用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

【讨论】:

在稀疏的 uint32 上更正,但是,double 应该有一个可接受的范围。 对,我试图强调原始数据为 uint32 并没有帮助。【参考方案2】:

如果您关心数据文件的大小尽可能小,以下是一些建议:

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

这里有几个例子来说明:

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。

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

【讨论】:

【参考方案3】:

数据是如何产生的?您需要如何访问数据?

如果我计算正确,如果它是双倍的,变量小于 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')

【讨论】:

以上是关于在 MATLAB 中存储 16 × (2^20) 矩阵的最佳方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章

matlab中求解二元函数的极小值,20分.

在 Matlab 中使用大矩阵

MATLAB绘图及例子总结

matlab中怎么修改变量的类型

如何用matlab实现fir低通滤波器

Matlab:组装其#cols和#rows存储在向量中的子矩阵