Question

Est-ce que quelqu'un ici sait comment supprimer une variable d'un fichier Matlab? Je sais que vous pouvez ajouter des variables à un fichier existant Matlab en utilisant la méthode save -append, mais il n'y a pas de documentation sur la façon de supprimer des variables à partir du fichier.

Avant que quelqu'un dit, « juste sauver », parce que je suis son économie étapes de traitement intermédiaires sur le disque pour atténuer les problèmes de mémoire, et à la fin il y aura près de 10 Go de données intermédiaires par routine d'analyse. Merci!

Était-ce utile?

La solution

Il est intéressant, vous pouvez utiliser l'option -append avec ENREGISTRER efficacement effacer les données d'un fichier .mat. Notez cet extrait de la documentation (gras ajouté par moi):

  
    

Pour les fichiers MAT, -append ajoute de nouvelles variables au fichier ou remplace les valeurs enregistrées de variables existantes avec des valeurs dans l'espace de travail .

  

En d'autres termes, si une variable dans votre fichier .mat est appelé A, vous pouvez enregistrer sur cette variable avec nouveau copie de A (que vous avez défini à []) en utilisant le -append option. Il y aura toujours une variable appelée A dans le fichier .mat, mais il sera vide et réduire ainsi la taille totale du fichier.

Voici un exemple:

>> 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 taille du fichier sera d'environ 7,21 MB. Maintenant, faites ceci:

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

Et maintenant la taille du fichier sera d'environ 169 octets. La variable est toujours là, mais il est vide.

Autres conseils

10 Go de données? Mise à jour de fichiers MAT multi-variables pourrait obtenir en raison coûteuse aux frais généraux de format MAT. Pensez à diviser les données et l'enregistrement de chaque variable à un autre fichier MAT, en utilisant des répertoires pour l'organisation si nécessaire. Même si vous aviez une fonction pratique pour supprimer les variables d'un fichier MAT, il serait inefficace. Les variables dans un fichier MAT sont layed sur jointive, afin de remplacer une variable peut exiger la lecture et l'écriture une grande partie du reste. Si elles sont dans des fichiers séparés, vous pouvez simplement supprimer le fichier entier, ce qui est rapide.

Pour voir en action, essayez ce code, pas à pas dans dans le débogueur en utilisant quelque chose comme Process Explorer (sous Windows) pour surveiller son activité E / S.

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;

Sur ma machine, les résultats se présentent comme suit. (Lecture et écriture sont cumulatifs, Le temps est par opération).

                    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

Notez que la mise à jour de la petite variable x est plus cher que la mise à jour de la grande y. Une grande partie de cette activité E / S est un travail d'entretien « redondant » pour conserver le format de fichier MAT organisé et vont disparaître si chaque variable est dans son propre fichier.

En outre, essayez de garder ces fichiers sur le système de fichiers local; ce sera beaucoup plus rapide que les lecteurs réseau. Si elles ont besoin d'aller sur un lecteur réseau, tenez compte faire la sauvegarde () et charge () sur les fichiers temporaires locaux (peut-être choisi avec tempname ()), puis les copier vers / depuis le lecteur réseau. Matlab économisons et la charge ont tendance à être beaucoup plus rapide avec les systèmes de fichiers locaux, assez pour que locale sauvegarde / chargement en plus d'une copie peut être une victoire nette importante.


Voici une implémentation de base qui vous permettra d'enregistrer des variables dans des fichiers séparés en utilisant les signatures familières de sauvegarde () et charge (). Ils sont préfixés par « d » pour indiquer qu'ils sont les versions annuaire. Ils utilisent quelques trucs avec Evalin () et assignin (), donc je pensais que ce serait une valeur affichant le code complet.

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

Voici la charge () équivalente.

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 () est l'équivalent de whos ( '- fichier').

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

Et ddelete () pour supprimer les variables individuelles comme vous avez demandé.

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

La seule façon de faire ce que je sais est d'utiliser la fonction API fichier MAT matDeleteVariable. Il serait, je suppose, être assez facile d'écrire un Fortran ou de routine C pour ce faire, mais il ne semble que beaucoup d'efforts pour quelque chose qui devrait être beaucoup plus facile.

Je vous suggère de charger les variables à partir du fichier .mat que vous voulez garder, et de les enregistrer dans un nouveau fichier .mat. Si nécessaire, vous pouvez charger et enregistrer (en utilisant '-append') dans une boucle.

S = load(filename, '-mat', variablesYouWantToKeep);
save(newFilename,'-struct',S,variablesYouWantToKeep);
%# then you can delete the old file
delete(filename)
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top