代码之家  ›  专栏  ›  技术社区  ›  eykanal

从.mat文件中删除变量

  •  16
  • eykanal  · 技术社区  · 14 年前

    这里有人知道怎么做吗 删除 一个来自matlab文件的变量?我知道您可以使用现有的MATLAB文件添加变量。 save -append 方法,但没有关于如何从文件中删除变量的文档。

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

    4 回复  |  直到 12 年前
        1
  •  13
  •   gnovice    14 年前

    有趣的是,您可以使用 -append 选项 SAVE 有效地 从.mat文件中删除数据。注意这段文档摘录(我加了粗体字):

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

    换句话说,如果.mat文件中的变量被调用 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
    

    文件大小约为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
    

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

        2
  •  11
  •   Andrew Janke    14 年前

    10GB的数据?由于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;
    

    在我的机器上,结果是这样的。(读和写是累积的,时间是每次操作的时间。)

                        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
    

    请注意,更新小的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
    

    这是等效的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
    

    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$', '');
    

    和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
    
        3
  •  1
  •   High Performance Mark    14 年前

    我知道唯一的方法是使用MAT file API函数 matDeleteVariable . 我想,编写一个Fortran或C例程来完成这项工作是相当容易的,但是对于一些本应该容易得多的事情来说,这看起来确实是一个很大的努力。

        4
  •  0
  •   Jonas    14 年前

    我建议您从要保存的.mat文件中加载变量,并将它们保存到新的.mat文件中。如果需要,可以加载和保存(使用 '-append' )在一个循环中。

    S = load(filename, '-mat', variablesYouWantToKeep);
    save(newFilename,'-struct',S,variablesYouWantToKeep);
    %# then you can delete the old file
    delete(filename)
    
    推荐文章