从.mat文件中删除变量

eyk*_*nal 16 matlab mat-file

有没有人知道如何从matlab文件中删除变量?我知道您可以使用该save -append方法将变量添加到现有的matlab文件中,但是没有关于如何从文件中删除变量的文档.

在有人说"只是保存它"之前,它是因为我将中间处理步骤保存到磁盘以缓解内存问题,最终每个分析例程将有近10 GB的中间数据.谢谢!

gno*_*ice 13

有趣的是,你可以使用-append选项和SAVE有效地从.MAT文件擦除数据.请注意文档中的摘录(由我添加的粗体):

对于MAT文件,-append将新变量添加到文件中或使用工作空间中的值替换现有变量的已保存值.

换句话说,如果调用.mat文件中的变量,则A可以使用该选项将副本A(已设置为[])保存到该变量上-append.仍然会A在.mat文件中调用一个变量,但它将为空,从而减少总文件大小.

这是一个例子:

>> A = rand(1000);            %# Create a 1000-by-1000 matrix of random values
>> save('savetest.mat','A');  %# Save A to a file
>> whos -file savetest.mat    %# Look at the .mat file contents
  Name         Size                Bytes  Class     Attributes

  A         1000x1000            8000000  double
Run Code Online (Sandbox Code Playgroud)

文件大小约为7.21 MB.现在这样做:

>> A = [];                              %# Set the variable A to empty
>> save('savetest.mat','A','-append');  %# Overwrite A in the file
>> whos -file savetest.mat              %# Look at the .mat file contents
  Name      Size            Bytes  Class     Attributes

  A         0x0                 0  double
Run Code Online (Sandbox Code Playgroud)

现在文件大小约为169字节.变量仍在那里,但它是空的.


And*_*nke 11

10 GB的数据?由于MAT格式开销,更新多变量MAT文件可能会变得昂贵.考虑拆分数据并将每个变量保存到不同的MAT文件,必要时使用目录进行组织.即使你有一个方便的功能来从MAT文件中删除变量,它也会效率低下.MAT文件中的变量是连续布局的,因此替换一个变量可能需要读取和写入其余的大部分内容.如果它们位于单独的文件中,您可以删除整个文件,这很快.

要查看此操作,请尝试使用此代码,在调试器中逐步执行此代码,同时使用Process Explorer(在Windows上)监视其I/O活动.

function replace_vars_in_matfile

x = 1;
% Random dummy data; zeros would compress really well and throw off results
y = randi(intmax('uint8')-1, 100*(2^20), 1, 'uint8');

tic; save test.mat x y; toc;
x = 2;
tic; save -append test.mat x; toc;
y = y + 1;
tic; save -append test.mat y; toc;
Run Code Online (Sandbox Code Playgroud)

在我的机器上,结果看起来像这样.(读取和写入是累积的,时间是每次操作.)

                    Read (MB)      Write (MB)       Time (sec)
before any write:   25             0
first write:        25             105              3.7
append x:           235            315              3.6
append y:           235            420              3.8
Run Code Online (Sandbox Code Playgroud)

请注意,更新小x变量比更新大y更昂贵.这种I/O活动大部分是"冗余"的内务处理工作,以保持MAT文件格式的有序,并且如果每个变量都在自己的文件中,它将消失.

另外,尝试将这些文件保留在本地文件系统上; 它将比网络驱动器快得多.如果他们需要继续使用网络驱动器,请考虑对本地临时文件(可能选择tempname())执行save()和load(),然后将它们复制到网络驱动器或从网络驱动器复制它们.使用本地文件系统,Matlab的保存和加载速度往往要快得多,因此本地保存/加载加上副本可以获得实质性的净胜利.


这是一个基本实现,它允许您使用熟悉的save()和load()签名将变量保存到单独的文件中.它们以"d"为前缀,表示它们是基于目录的版本.他们使用evalin()和assignin()的一些技巧,所以我认为值得发布完整的代码.

function dsave(file, varargin)
%DSAVE Like save, but each var in its own file
%
% dsave filename var1 var2 var3...
if nargin < 1 || isempty(file); file = 'matlab';  end
[tfStruct,loc] = ismember({'-struct'}, varargin);
args = varargin;
args(loc(tfStruct)) = [];
if ~all(cellfun(@isvarname, args))
    error('Invalid arguments. Usage: dsave filename <-struct> var1 var2 var3 ...');
end
if tfStruct
    structVarName = args{1};
    s = evalin('caller', structVarName);
else
    varNames = args;
    if isempty(args)
        w = evalin('caller','whos');
        varNames = { w.name };
    end
    captureExpr = ['struct(' ...
        join(',', cellfun(@(x){sprintf('''%s'',{%s}',x,x)}, varNames)) ')'];
    s = evalin('caller', captureExpr);
end

% Use Java checks to avoid partial path ambiguity
jFile = java.io.File(file);
if ~jFile.exists()
    ok = mkdir(file);
    if ~ok; 
        error('failed creating dsave dir %s', file);
    end
elseif ~jFile.isDirectory()
    error('Cannot save: destination exists but is not a dir: %s', file);
end
names = fieldnames(s);
for i = 1:numel(names)
    varFile = fullfile(file, [names{i} '.mat']);
    varStruct = struct(names{i}, {s.(names{i})});
    save(varFile, '-struct', 'varStruct');
end

function out = join(Glue, Strings)
Strings = cellstr(Strings);
if length( Strings ) == 0
    out = '';
elseif length( Strings ) == 1
    out = Strings{1};
else
    Glue = sprintf( Glue ); % Support escape sequences
    out = strcat( Strings(1:end-1), { Glue } );
    out = [ out{:} Strings{end} ];
end
Run Code Online (Sandbox Code Playgroud)

这是load()的等价物.

function out = dload(file,varargin)
%DLOAD Like load, but each var in its own file
if nargin < 1 || isempty(file); file = 'matlab'; end
varNames = varargin;
if ~exist(file, 'dir')
    error('Not a dsave dir: %s', file);
end
if isempty(varNames)
    d = dir(file);
    varNames = regexprep(setdiff(ls(file), {'.','..'}), '\.mat$', '');
end

out = struct;
for i = 1:numel(varNames)
    name = varNames{i};
    tmp = load(fullfile(file, [name '.mat']));
    out.(name) = tmp.(name);
end

if nargout == 0
    for i = 1:numel(varNames)
        assignin('caller', varNames{i}, out.(varNames{i}));
    end
    clear out
end
Run Code Online (Sandbox Code Playgroud)

Dwhos()相当于whos(' - file').

function out = dwhos(file)
%DWHOS List variable names in a dsave dir
if nargin < 1 || isempty(file); file = 'matlab'; end
out = regexprep(setdiff(ls(file), {'.','..'}), '\.mat$', '');
Run Code Online (Sandbox Code Playgroud)

并且ddelete()删除你问的个别变量.

function ddelete(file,varargin)
%DDELETE Delete variables from a dsave dir
if nargin < 1 || isempty(file); file = 'matlab'; end
varNames = varargin;
for i = 1:numel(varNames)
    delete(fullfile(file, [varNames{i} '.mat']));
end
Run Code Online (Sandbox Code Playgroud)