10 GB de datos? Actualizar los archivos MAT multivariables podría ser costoso debido a la sobrecarga del formato MAT. Considere dividir los datos y guardar cada variable en un archivo MAT diferente, utilizando directorios para la organización si es necesario. Incluso si tuviera una función conveniente para eliminar variables de un archivo MAT, sería ineficiente. Las variables en un archivo MAT se muestran contiguamente, por lo que reemplazar una variable puede requerir leer y escribir gran parte del resto. Si están en archivos separados, puede simplemente eliminar el archivo completo, que es rápido.
Para ver esto en acción, pruebe este código, piénselo en el depurador mientras usa algo como Process Explorer (en Windows) para controlar su actividad de 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;
En mi máquina, los resultados se ven así.(Lectura y escritura son acumulativos, El tiempo es por operación.)
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
en cuenta que la actualización de la pequeña variable x es más cara que la actualización de la gran y. Gran parte de esta actividad de E/S es trabajo de limpieza "redundante" para mantener organizado el formato de archivo MAT, y desaparecerá si cada variable está en su propio archivo.
Además, intente mantener estos archivos en el sistema de archivos local; será mucho más rápido que las unidades de red. Si necesitan conectarse a una unidad de red, considere guardar() y cargar() en archivos temporales locales (tal vez elegidos con tempname()) y luego copiarlos a/desde la unidad de red. El ahorro y la carga de Matlab tienden a ser mucho más rápidos con los sistemas de archivos locales, lo suficiente como para que la operación de guardar/cargar más una copia local sea una ganancia neta sustancial.
Aquí es una implementación básica que le permitirá guardar las variables en archivos separados utilizando el familiar save() y la carga() las firmas. Están prefijados con "d" para indicar que son las versiones basadas en el directorio. Usan algunos trucos con evalin() y assignin(), así que pensé que valdría la pena publicar el código 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
Aquí está el equivalente a 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() es el equivalente de 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$', '');
Y ddelete() para eliminar las variables individuales como usted solicitó.
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
+1 para la solución inteligente! – Jonas