質問
ここの誰かが方法を知っていますか 消去 MATLABファイルからの変数?既存のMATLABファイルに変数を追加できることを知っています save -append
方法ですが、ファイルから変数を削除する方法に関するドキュメントはありません。
誰かが「ただ保存するだけ」と言う前に、それはメモリの問題を軽減するためにディスクに中間処理手順を保存しているからです。最終的には、分析ルーチンごとに10 GBの中間データがあります。ありがとう!
解決
興味深いことに、使用できます -append
でオプション 保存する に 効果的に .matファイルからデータを消去します。ドキュメントからのこの抜粋に注意してください(私によって追加された太字):
マットファイルの場合、
-append
ファイルに新しい変数を追加します 既存の変数の保存された値をワークスペース内の値に置き換えます.
言い換えれば、.matファイルの変数が呼び出された場合 A
, 、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 MBになります。今これを行います:
>> 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 GBのデータ?マットフォーマットのオーバーヘッドにより、多変数マットファイルを更新すると高価になる可能性があります。必要に応じて、データを分割して各変数を別のマットファイルに保存し、組織用のディレクトリを使用して検討してください。マットファイルから変数を削除する便利な機能があったとしても、それは非効率的です。マットファイルの変数は連続してレイアウトされるため、1つの変数を交換するには、残りの多くを読み書きする必要があります。それらが別々のファイルにある場合、ファイル全体を削除するだけで、これは高速です。
これを実際に確認するには、このコードを試して、プロセスエクスプローラー(Windows)のようなものを使用してI/Oアクティビティを監視しながら、デバッガーで踏み込んでください。
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を更新するよりも高価であることに注意してください。このI/Oアクティビティの多くは、MATファイル形式を整理するための「冗長」ハウスキーピング作業であり、各変数が独自のファイルにある場合に消えます。
また、これらのファイルをローカルファイルシステムに保持してください。ネットワークドライブよりもはるかに高速になります。ネットワークドライブにアクセスする必要がある場合は、ローカルTEMPファイルでSave()とLoad()を実行し(TempName())、ネットワークドライブにCOPYでコピーすることを検討してください。 Matlabの保存と負荷はローカルファイルシステムを使用するとはるかに高速になる傾向があります。
馴染みのあるsave()とload()署名を使用してファイルを分離するように変数を保存できる基本的な実装を次に示します。それらは、ディレクトリベースのバージョンであることを示すために「D」が付いています。彼らはevalin()とassignin()でいくつかのトリックを使用しているので、完全なコードを投稿する価値があると思いました。
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
これが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()は、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$', '');
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機能を使用することです 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)