Frage

Hat jemand hier wissen, wie man löschen eine Variable aus einer Matlab-Datei? Ich weiß, dass Sie Variablen zu einer vorhandenen Matlab-Datei mit der save -append Methode hinzufügen können, aber es gibt keine Dokumentation, wie die Variablen aus der Datei zu löschen.

Bevor jemand sagt, „nur speichert es“, sein, weil ich sparende Zwischenverarbeitungsschritte Plattenspeicher Probleme zu lindern, und am Ende wird es fast 10 GB Zwischendaten pro Analyseroutine sein. Dank!

War es hilfreich?

Lösung

Interessanterweise können Sie die -append Option mit SPAREN effektiv Lösch Daten aus einer .mat Datei. Notieren Sie sich diesen Auszug aus der Dokumentation (fett von mir hinzugefügt):

  
    

Für MAT-Dateien, fügt -append neue Variablen in die Datei oder ersetzt die gespeicherten Werte von vorhandenen Variablen mit Werten im Arbeitsbereich .

  

Mit anderen Worten, wenn eine Variable in Ihrer .mat Datei A aufgerufen wird, können Sie sparen über diese Variable mit einem neuen Kopieren von A (die Sie auf [] festgelegt haben) mit dem -append Möglichkeit. Es wird immer noch eine Variable namens A in der .mat Datei sein, aber es wird leer sein und somit die gesamte Dateigröße reduzieren.

Hier ist ein Beispiel:

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

Die Dateigröße wird etwa 7,21 MB groß sein. Nun dies zu tun:

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

Und nun die Dateigröße bei rund 169 Byte sein. Die Variable ist noch drin, aber es ist leer.

Andere Tipps

10 GB Daten? multivariable MAT-Dateien Aktualisierung könnte teuer aufgrund MAT-Format Overhead bekommen. Betrachten Aufspaltung der Daten und jede Variable in eine andere MAT-Datei speichern, indem Verzeichnisse für die Organisation, wenn nötig. Auch wenn Sie von einer MAT-Datei eine komfortable Funktion löschen Variablen hätten, wäre es ineffizient sein. Die Variablen in einer MAT-Datei zusammenhängend gelegt aus, so eine Variable ersetzt verlangen kann das Lesen und viel von dem Rest zu schreiben. Wenn sie in separaten Dateien sind, können Sie einfach die ganze Datei löschen, was schnell ist.

Um dies zu sehen in Aktion, versuchen Sie diesen Code, durch sie im Debugger Schritt während so etwas wie Process Explorer verwenden (unter Windows) seine E / A-Aktivität zu überwachen.

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;

Auf meinem Rechner sieht das Ergebnis wie folgt aus. (Lesen und Schreiben sind kumulativ, Zeit pro Betrieb ist.)

                    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

Diese Bekanntmachung enthält die kleinen x variable Aktualisierung ist teurer als der großen y aktualisieren. Ein großer Teil dieser E / A-Aktivität ist „redundant“ Housekeeping Arbeit des MAT-Dateiformat organisiert zu halten, und geht weg, wenn jede Variable in einer eigenen Datei ist.

Versuchen Sie auch, diese Dateien auf dem lokalen Dateisystem zu halten; es wird viel schneller als Netzlaufwerk sein. Wenn sie auf einem Netzlaufwerk gehen müssen, sollten Sie tun, die save () und Last () auf lokale temporären Dateien (vielleicht mit tempname gewählt ()) und sie dann zu / von dem Netzlaufwerk zu kopieren. Matlab speichert und lädt dazu neigen, viel schneller mit lokalen Dateisystemen zu sein, genug, so dass lokale Speicher / Laden plus eine Kopie kann ein erheblicher Netto-Gewinn sein.


mit der vertrauten save () und Last () Unterschriften

Hier ist eine grundlegende Implementierung, die Sie Variablen separate Dateien speichern lassen. Sie sind mit „d“ vorangestellt, um anzuzeigen, sie dem Verzeichnis-basierten Versionen sind. Sie nutzen ein paar Tricks mit evalin () und assignin (), so dachte ich, es lohnt sich die Buchung der vollständige Code wäre.

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

Hier ist die Last () gleichwertig.

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 () ist das Äquivalent von whos ( '- Datei).

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

Und ddelete (), um die einzelnen Variablen zu löschen, wie Sie gefragt.

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

Der einzige Weg, dies zu tun, dass ich weiß, ist die MAT-Datei-API-Funktion matDeleteVariable zu verwenden. Es wäre, glaube ich, werden ganz einfach, ein Fortran oder C-Routine zu schreiben, dies zu tun, aber es scheint, wie viel Aufwand für etwas was viel einfacher sein.

Ich schlage vor, Sie die Variablen aus der .mat Datei laden Sie behalten möchten, und speichern Sie sie auf eine neue .mat Datei. Bei Bedarf können Sie laden und speichern (mit '-append') in einer Schleife.

S = load(filename, '-mat', variablesYouWantToKeep);
save(newFilename,'-struct',S,variablesYouWantToKeep);
%# then you can delete the old file
delete(filename)
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top