Domanda

Qualcuno qui sa come Elimina di una variabile da un file MATLAB? So che è possibile aggiungere le variabili di un file MATLAB esistente utilizzando il metodo save -append, ma non c'è alcuna documentazione su come eliminare le variabili dal file.

Prima che qualcuno dice, "solo salverà", è perché sto risparmiando fasi di lavorazione intermedie su disco per alleviare problemi di memoria, e alla fine ci saranno quasi 10 GB di dati intermedi per le analisi di routine. Grazie!

È stato utile?

Soluzione

È interessante notare, è possibile utilizzare l'opzione -append con SAVE per efficace Cancella dati da un file .mat. Nota questo estratto dalla documentazione (grassetto aggiunto da me):

  
    

Per MAT-files, -append aggiunge nuove variabili al file o sostituisce i valori salvati di variabili esistenti con valori nello spazio di lavoro .

  

In altre parole, se una variabile nel file .mat si chiama A, è possibile risparmiare più di quella variabile con un nuovo copia di A (che hai impostato per []) utilizzando il -append opzione. Ci sarà ancora una variabile chiamata A nel file .mat, ma sarà vuota e quindi ridurre la dimensione totale del file.

Ecco un esempio:

>> 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

La dimensione del file sarà di circa 7,21 MB. Ora fare questo:

>> 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

E ora la dimensione del file sarà di circa 169 byte. La variabile è ancora lì, ma è vuota.

Altri suggerimenti

10 GB di dati? Aggiornamento dei file MAT multi-variabile potrebbe ottenere costoso a causa di formato MAT in testa. Pensare di dividere i dati e salvare ogni variabile in un file MAT diverso, usando le directory per l'organizzazione, se necessario. Anche se si ha una comoda funzione per eliminare le variabili da un file MAT, sarebbe inefficiente. Le variabili in un file MAT vengono spiegate in modo contiguo, quindi la sostituzione di una variabile può richiedere la lettura e la scrittura di gran parte del resto. Se sono in file separati, si può semplicemente eliminare l'intero file, che è veloce.

Per vedere questo in azione, provare questo codice, facendo un passo attraverso di essa nel debugger mentre si utilizza qualcosa come Process Explorer (su Windows) per monitorare l'attività di 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;

Sulla mia macchina, i risultati simile a questa. (Lettura e scrittura sono cumulativi, il tempo è per operazione.)

                    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

Si noti che l'aggiornamento della variabile x piccolo è più costoso di aggiornare il grande y. Gran parte di questa attività di I / O è "ridondante" lavoro di pulizia per mantenere il formato di file MAT organizzata, e andranno via se ogni variabile è nel proprio file.

Inoltre, cercare di mantenere questi file sul file system locale; sarà molto più veloce di unità di rete. Se hanno bisogno di andare su un'unità di rete, in considerazione di fare il salvataggio () e carico () su file temporanei locali (forse scelti con tempname ()) e poi copiandoli da / per l'unità di rete. di salvataggio Matlab e carico tendono ad essere molto più veloce con file system locali, tanto che locale Save / carico più una copia può essere una vittoria netta sostanziale.


Ecco un'implementazione di base che vi permetterà di salvare le variabili in file separati utilizzando il familiare save () e carico) le firme (. Sono prefisso "d" per indicare che sono le versioni basata su directory. Usano alcuni trucchi con Evalin () e assignin (), così ho pensato che sarebbe valsa la pubblicazione del codice completo.

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

Ecco il carico () equivalente.

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 () è l'equivalente di 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$', '');

E ddelete () per eliminare le singole variabili come hai chiesto.

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

L'unico modo per farlo che so è quello di utilizzare il MAT-file di funzione API matDeleteVariable. Sarebbe, credo, essere abbastanza facile scrivere una routine Fortran o C per fare questo, ma lo fa sembrare un grande sforzo per qualcosa che dovrebbe essere molto più facile.

Vi suggerisco di caricare le variabili dal file .mat che si desidera conservare, e salvarli in un nuovo file .mat. Se necessario, è possibile caricare e salvare (utilizzando '-append') in un ciclo.

S = load(filename, '-mat', variablesYouWantToKeep);
save(newFilename,'-struct',S,variablesYouWantToKeep);
%# then you can delete the old file
delete(filename)
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top