Вопрос

Кто-нибудь здесь знает, как удалять Переменная от файла MatLab? Я знаю, что вы можете добавить переменные в существующий файл MATLAB, используя save -append Метод, но нет документации о том, как удалить переменные из файла.

До того, как кто-то говорит: «Просто сохраните его», это, потому что я экономлю промежуточную обработку шагов к диску, чтобы облегчить проблемы с памятью, а в конце концов будет почти 10 ГБ промежуточных данных в процедуре анализа. Спасибо!

Это было полезно?

Решение

Интересно, вы можете использовать -append вариант СПАСТИ к эффективно Стереть данные из файла .mat. Обратите внимание на этот выдержка из документации (Bold добавлено мной):

Для матовых файлов, -append Добавляет новые переменные в файл или Заменяет сохраненные значения существующих переменных со значениями в рабочем пространстве.

Другими словами, если переменная в вашем файле .mat называется A, вы можете сохранить эту переменную с помощью новый копия A (что вы установили []) с использованием -append вариант. Там еще будет переменная называется 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 МБ. Теперь сделайте это:

>> 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 байтов. Переменная все еще там, но она пуста.

Другие советы

10 ГБ данных? Обновление файлов Multi-Privable Mat может стать дорогим из-за форматирования циновки накладной. Рассмотрите расщепление данных и сохранение каждой переменной в другой файл MAT, используя каталоги для организации, если это необходимо. Даже если у вас была удобная функция, чтобы удалить переменные из файла MAT, это было бы неэффективно. Переменные в файле коврика прокладываются непрерывно, поэтому замена одной переменной может потребовать чтения и записи большого количества остальных. Если они в отдельных файлах, вы можете просто удалить весь файл, который быстро.

Чтобы увидеть это в действии, попробуйте этот код, переходя через него в отладчик, используя что-то вроде процесса Explorer (в Windows), чтобы отслеживать свою активность ввода-вывода.

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. Большая часть этой активности ввода / вывода - «избыточная» работа в домашних хозяйстве, чтобы сохранить формат файла MAT, и уйдет, если каждая переменная находится в собственном файле.

Кроме того, попробуйте сохранить эти файлы на локальной файловой системе; Это будет намного быстрее, чем сетевые диски. Если им нужно пойти на сетевой диск, рассмотрите возможность выполнения файлов Save () и Load () в локальных температурах Temp (возможно, выбрано с помощью Tempname ()), а затем копирование их в / из сетевого диска. Сохранение и загрузка Matlab, как правило, намного быстрее с локальными файловыми системами, достаточно, чтобы локальная экономия / нагрузка плюс копия может быть существенной сети.


Вот базовая реализация, которая позволит вам сохранить переменные для отдельных файлов, используя знакомые подписи сохранения () и нагрузки (). Они префиксированы с помощью «D», чтобы указать, что они на основе каталога версии. Они используют некоторые трюки с Evalin () и russian (), поэтому я подумал, что стоило бы разместить полный код.

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

Вот эквивалент нагрузки ().

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 («- файл»).

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

Единственный способ сделать это, что я знаю, это использовать функцию API файла MAT-файла matDeleteVariable. Отказ Это будет, я думаю, быть довольно легко написать рутина Fortran или C, чтобы сделать это, но это похоже на много усилий для чего-то, что должно быть намного проще.

Я предлагаю вам загрузить переменные из файла .mat, который вы хотите сохранить, и сохранить их в новом файле .mat. При необходимости вы можете загрузить и сохранить (используя '-append') в петле.

S = load(filename, '-mat', variablesYouWantToKeep);
save(newFilename,'-struct',S,variablesYouWantToKeep);
%# then you can delete the old file
delete(filename)
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top