我在一台有很多RAM的机器上有一个框架,它产生带有一个非常大的和特别命名的矩阵的MAT文件。这个矩阵的计算只进行一次,并且花费了大量的时间。最后,将其存储到磁盘上的MAT文件中。
在使用阶段,应加载此MAT文件。问题是我不需要所有的数据--只需要从矩阵中选择特定的列。
例如,我在一个大小为500x250000的文件crfh.mat中有一个矩阵'sign‘,类型为double。我可能感兴趣的是仅使用该矩阵中的‘id’加载向量:
sign( :,ids )
有没有办法做到这一点?我在网上搜索了一下,似乎没有人表达过对这种功能的需求。我正在考虑编写一个MEX函数select_mat(),如下所示:
sign_sub = select_mat( mat_file,var_name,ids );
发布于 2011-03-18 02:56:06
如果你有一个非常大的矩阵,你只想加载其中的一部分,我不会将它另存为.MAT文件。将矩阵写入到它自己的二进制文件中会更有效。然后,您可以使用像FSEEK这样的函数跳到文件中的各种索引点,只读取您需要的内容。例如,让我们首先使用函数FWRITE将一个较小的样本矩阵保存为二进制文件
>> M = magic(5) %# A sample matrix
M =
17 24 1 8 15
23 5 7 14 16
4 6 13 20 22
10 12 19 21 3
11 18 25 2 9
>> fid = fopen('bigmatrix.dat','w'); %# Open the file for writing
>> fwrite(fid,size(M),'uint8','l'); %# Write the matrix size (needed later) as
%# 2 unsigned 8-bit (1-byte) integers
>> fwrite(fid,M,'uint8','l'); %# Write the matrix data as unsigned 8-bit
%# (1-byte) integers
>> fclose(fid); %# Close the file现在,我们可以使用函数FREAD和FSEEK读取第三列
>> colIndex = 3;
>> fid = fopen('bigmatrix.dat','r'); %# Open the file for reading
>> sizeM = fread(fid,2,'uint8','l'); %# Read the first two bytes to get the
%# size of the matrix in the file
>> fseek(fid,sizeM(1)*(colIndex-1),0); %# Seek forward by an amount of two
%# columns worth of bytes
>> colData = fread(fid,sizeM(1),'uint8','l'); %# Read column 3 data
>> fclose(fid); %# Close the file
>> disp(colData) %# Confirm that the right column was read
1
7
13
19
25这只是一个简单的例子。您可能希望向文件中写入其他信息(即header information),例如矩阵中每个值的字节大小或数据类型。这看起来可能比仅仅将内容转储到.MAT文件要多一些工作,事实也的确如此,但是如果文件IO操作的效率是一个大问题,那么在这种情况下最好创建自己的文件格式来处理数据。
发布于 2011-03-18 02:29:32
您可以从包含多个变量的.mat文件中加载特定变量。然而,我不认为你可以从MATLAB中的一个变量中加载一组任意的索引。
也就是说,如果您的问题属于只需要访问特定行/列的类型,那么我可以为您提供一个解决方法。
您可以从矩阵创建一个struct,将每列作为单独的字段,然后使用-struct选项保存.mat文件,以便将每个字段另存为单独的变量。这样,你就可以拿出你想要的了。
dummy=randn(100,200);%# this is a test matrix
[dim1,dim2]=size(dummy);
dummyCell=mat2cell(dummy,dim1,ones(dim2,1));%# create a cell from the matrix
fieldNames=strcat(repmat({'col'},1,dim2),cellfun(@num2str,mat2cell(1:dim2,1,ones(dim2,1)),'UniformOutput',false));%# generate fieldnames for the struct
dummyStruct=cell2struct(dummyCell,fieldNames,2);%# create the struct
save('myDummyFile','-struct','dummyStruct')我不知道有什么方法可以直接将矩阵转换为结构。因此,您首先将每一列拆分为多个单元格(排序是因为您指出需要访问这些列。如果你需要这些行,你就得换行)。这是在单元格dummyCell中。现在,为了保存到一个结构,我们需要生成字段名。这是在字符串单元格fieldNames中。它会生成col1、col2等格式的字段名。如果你愿意,你可以给它命名为一些有意义的东西。然后,我们将每个单元格分配给相应的字段名称,从而将cell转换为struct。最后,使用-struct选项保存mat文件,该选项告诉MATLAB将每个字段保存为单独的变量。所有这些都应该在你的程序保存这个巨大的mat文件时完成。现在,如果你需要访问,比如说col52,你所需要做的就是load('myDummyFile','col52')。如果需要,您还可以加载多个。
请记住,如果您对索引要求有顺序(即,每行/每列),则此方法效果很好。如果您需要访问矩阵中的任意索引,则此方法将不起作用。在创建单元/结构并保存它时,可能会有一些相关的开销。但是,如果你只存一次钱,但要经常访问,这将是值得的。
如果你的矩阵很大(按照今天的标准,500x25万并不是那么大),你必须注意这种方法的内存问题,因为我们正在将整个矩阵复制到一个cell & struct中。我一步一步地编写它,以便更容易理解,但您可以通过从dummy创建一个单元格并将其赋值给自身和类似的结构来减少重复。但是,这只会将副本数量减少1,因为Matlab仍然需要将变量复制到内存中,以便在操作后分配给自己。
https://stackoverflow.com/questions/5340779
复制相似问题