سؤال

هل يعرف أي شخص هنا كيف حذف متغير من ملف MATLAB؟ أعلم أنه يمكنك إضافة متغيرات إلى ملف MATLAB موجود باستخدام save -append الطريقة ، ولكن لا توجد وثائق حول كيفية حذف المتغيرات من الملف.

قبل أن يقول أحدهم ، "ما عليك سوى حفظه" ، فهذا لأنني أقوم بتوفير خطوات معالجة وسيطة لتصميم مشاكل الذاكرة ، وفي النهاية سيكون هناك ما يقرب من 10 جيجابايت من البيانات الوسيطة لكل روتين تحليل. شكرًا!

هل كانت مفيدة؟

المحلول

ومن المثير للاهتمام ، يمكنك استخدام -append الخيار مع حفظ إلى على نحو فعال محو البيانات من ملف .MAT. لاحظ هذا المقتطف من الوثائق (Bold Bold by Me):

لملفات حصيرة ، -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 غيغابايت من البيانات؟ يمكن أن يصبح تحديث ملفات حصيرة متعددة المتغيرات باهظة الثمن بسبب تنسيق MAT. فكر في تقسيم البيانات وحفظ كل متغير إلى ملف حصيرة مختلف ، باستخدام أدلة للتنظيم إذا لزم الأمر. حتى لو كان لديك وظيفة مريحة لحذف المتغيرات من ملف حصيرة ، فسيكون ذلك غير فعال. يتم وضع المتغيرات الموجودة في ملف حصيرة بشكل متجاور ، لذلك يمكن أن يتطلب استبدال متغير واحد القراءة وكتابة الكثير من الباقي. إذا كانت في ملفات منفصلة ، فيمكنك فقط حذف الملف بأكمله ، وهو سريع.

للاطلاع على ذلك في العمل ، جرب هذا الرمز ، وتجاوزه في مصحح الأخطاء أثناء استخدام شيء مثل Process 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 ()) ثم نسخها إلى/من محرك الشبكة. يميل Save and Load's Matlab إلى أن يكونوا أسرع بكثير مع أنظمة الملفات المحلية ، بما يكفي بحيث يمكن أن يكون حفظ/تحميل محلي بالإضافة إلى نسخة فوزًا صافيًا كبيرًا.


فيما يلي تطبيق أساسي يتيح لك حفظ المتغيرات لفصل الملفات باستخدام توقيعات Save () المألوفة () وتحميل (). إنها مسبوقة بـ "D" للإشارة إلى أنها الإصدارات القائمة على الدليل. يستخدمون بعض الحيل مع evalin () و ignin () ، لذلك اعتقدت أن الأمر يستحق نشر الكود الكامل.

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

الطريقة الوحيدة للقيام بذلك والتي أعرفها هي استخدام وظيفة واجهة برمجة تطبيقات FILE 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