Main Content

matlab.io.Datastore クラス

名前空間: matlab.io

基本データストア クラス

説明

matlab.io.Datastore は、カスタム データストア作成用の抽象クラスです。データストアは、特にデータが大きすぎてメモリに収まらない場合に、データの大規模な集合に反復してアクセスする上で便利です。抽象クラス Datastore は、MATLAB® 内のすべてのカスタム データストアに必要なインターフェイスを宣言して取得します。次の構文を使用してクラスを派生させます。

classdef MyDatastore < matlab.io.Datastore
    ...
end

カスタム データストアを実装するには、次を実行します。

  • クラス matlab.io.Datastore から継承

  • 4 つの必須メソッドを定義: hasdatareadreset、および progress

カスタム データストアの作成の詳細とその手順については、カスタム データストアの開発を参照してください。

メソッド

read

データストアからデータを読み取ります。

[data,info] = read(ds)

出力 data には任意のデータ型を指定できますが、垂直に連結可能でなければなりません。ベスト プラクティスは、出力 info を構造体として返すことです。

出力 data のデータ型が、関数 tall の出力のデータ型を決定します。

Access: Public, Abstract: true

hasdata

データが読み取り可能かどうかを判別します。出力は logical 型です。

tf = hasdata(ds)

Access: Public, Abstract: true

reset

データストアを、データが読み取られる前の初期状態にリセットします。

reset(ds)

Access: Public, Abstract: true

progress

既に読み取ったデータ量を判定します。

出力は、0 から 1 までの double 型のスカラーです。戻り値 0.5555% のデータを読み取ったことを意味します。

p = progress(ds)

Access: Public, Abstract: true, Hidden:true

preview

データのサブセットを返します。

data = preview(ds)

既定の実装では、データの最初の 8 行を返します。出力のデータ型は、read の出力のデータ型と同じです。

preview メソッドの既定の実装は、tall 配列の作成向けに最適化されていません。tall 配列のパフォーマンスを改善するには、データに基づいて実装を最適化します。

Access: Public

readall

データストアのすべてのデータを読み取ります。

data = readall(ds)

出力のデータ型は、read の出力のデータ型と同じです。データがメモリに収まらない場合、readall はエラーを返します。

readall メソッドの既定の実装は、tall 配列の作成向けに最適化されていません。tall 配列のパフォーマンスを改善するには、データに基づいて実装を最適化します。

Access: Public

combine

複数のデータストアのデータを統合します。

dsnew = combine(ds1,ds2,...,dsN)

出力 dsnew は、統合されたデータをもつ新しいデータストアです。CombinedDatastore オブジェクトとして返されます。データを順次読み取る SequentialDatastore オブジェクトを返すには、名前と値の引数 ReadOrder="sequential" を使用します。

Access: Public

transform

データストアを変換します。

dsnew = transform(ds,@fcn)

出力 dsnew は、変換後のデータを含む新しいデータストアです。TransformedDatastore オブジェクトとして返されます。

Access: Public

isPartitionable

データストアが分割可能かどうかを判別します。出力は logical 型です。

tf = isPartitionable(ds)

Access: Public

isSubsettable

データストアがサブセット化可能かどうかを判別します。出力は logical 型です。

tf = isSubsettable(ds)

Access: Public

isShuffleable

データストアがシャッフル可能かどうかを判別します。出力は logical 型です。

tf = isShuffleable(ds)

Access: Public

プロパティ

ハンドル プロパティをカスタム データストアに追加するには、copyElement メソッドを実装しなければなりません。たとえば、カスタム データストア内で DsFileSet オブジェクトをプロパティとして使用する場合は、copyElement メソッドを実装します。copyElement メソッドを実装することで、datastore オブジェクトのディープ コピーを作成できます。詳細については、コピー操作のカスタマイズを参照してください。copyElement メソッドの実装例については、カスタム データストアの開発を参照してください。

属性

Sealedfalse

クラス属性の詳細については、クラスの属性を参照してください。

すべて折りたたむ

順次処理向けにカスタム データまたは独自のデータを MATLAB® に取り込むためのデータストアを作成します。

カスタム データストアを実装するコードを含む、.m クラス定義ファイルを作成します。このファイルは作業フォルダーまたは MATLAB® パス上のフォルダーに保存しなければなりません。.m ファイルの名前は、オブジェクト コンストラクター関数の名前と同じでなければなりません。たとえば、コンストラクター関数の名前を MyDatastore にする場合、.m ファイルの名前は MyDatastore.m でなければなりません。.m クラス定義ファイルには、次の手順が含まれなければなりません。

  • 手順 1: データストア クラスから継承します。

  • 手順 2: コンストラクターと必須メソッドを定義します。

  • 手順 3: カスタム ファイルの読み取り関数を定義します。

これらの手順に加えて、データの処理と解析に必要なその他のプロパティまたはメソッドを定義します。

%% STEP 1: INHERIT FROM DATASTORE CLASSES
classdef MyDatastore < matlab.io.Datastore
    
    properties(Access = private)
        CurrentFileIndex double
        FileSet matlab.io.datastore.DsFileSet
    end
    
    % Property to support saving, loading, and processing of
    % datastore on different file system machines or clusters.
    % In addition, define the methods get.AlternateFileSystemRoots()
    % and set.AlternateFileSystemRoots() in the methods section. 
    properties(Dependent)
        AlternateFileSystemRoots
    end
    
    
%% STEP 2: DEFINE THE CONSTRUCTOR AND THE REQUIRED METHODS
    methods
        % Define your datastore constructor
        function myds = MyDatastore(location,altRoots)
            myds.FileSet = matlab.io.datastore.DsFileSet(location,...
                'FileExtensions','.bin', ...
                'FileSplitSize',8*1024);
            myds.CurrentFileIndex = 1;
             
            if nargin == 2
                 myds.AlternateFileSystemRoots = altRoots;
            end
            
            reset(myds);
        end
        
        % Define the hasdata method
        function tf = hasdata(myds)
            % Return true if more data is available
            tf = hasfile(myds.FileSet);
        end
        
        % Define the read method
        function [data,info] = read(myds)
            % Read data and information about the extracted data
            % See also: MyFileReader()
            if ~hasdata(myds)
                error(sprintf(['No more data to read.\nUse the reset ',... 
                     'method to reset the datastore to the start of ' ,...
                     'the data. \nBefore calling the read method, ',...
                     'check if data is available to read ',...
                     'by using the hasdata method.'])) 
            end
            
            fileInfoTbl = nextfile(myds.FileSet);
            data = MyFileReader(fileInfoTbl);
            info.Size = size(data);
            info.FileName = fileInfoTbl.FileName;
            info.Offset = fileInfoTbl.Offset;
            
            % Update CurrentFileIndex for tracking progress
            if fileInfoTbl.Offset + fileInfoTbl.SplitSize >= ...
                    fileInfoTbl.FileSize
                myds.CurrentFileIndex = myds.CurrentFileIndex + 1 ;
            end
        end
        
        % Define the reset method
        function reset(myds)
            % Reset to the start of the data
            reset(myds.FileSet);
            myds.CurrentFileIndex = 1;
        end

        % Getter for AlternateFileSystemRoots property
        function altRoots = get.AlternateFileSystemRoots(myds)
            altRoots = myds.FileSet.AlternateFileSystemRoots;
        end

        % Setter for AlternateFileSystemRoots property
        function set.AlternateFileSystemRoots(myds,altRoots)
            try
              % The DsFileSet object manages the AlternateFileSystemRoots
              % for your datastore
              myds.FileSet.AlternateFileSystemRoots = altRoots;

              % Reset the datastore
              reset(myds);  
            catch ME
              throw(ME);
            end
        end
    end
    
    methods (Hidden = true)          
        % Define the progress method
        function frac = progress(myds)
            % Determine percentage of data read from datastore
            if hasdata(myds) 
               frac = (myds.CurrentFileIndex-1)/...
                             myds.FileSet.NumFiles; 
            else 
               frac = 1;  
            end 
        end
    end
    
    methods(Access = protected)
        % If you use the  FileSet property in the datastore,
        % then you must define the copyElement method. The
        % copyElement method allows methods such as readall
        % and preview to remain stateless 
        function dscopy = copyElement(ds)
            dscopy = copyElement@matlab.mixin.Copyable(ds);
            dscopy.FileSet = copy(ds.FileSet);
        end
                
    end
end

%% STEP 3: IMPLEMENT YOUR CUSTOM FILE READING FUNCTION
function data = MyFileReader(fileInfoTbl)
% create a reader object using FileName
reader = matlab.io.datastore.DsFileReader(fileInfoTbl.FileName);

% seek to the offset
seek(reader,fileInfoTbl.Offset,'Origin','start-of-file');

% read fileInfoTbl.SplitSize amount of data
data = read(reader,fileInfoTbl.SplitSize);

end

カスタム データストアの準備ができました。MyDatastore を使用して、バイナリ データ ファイルを読み取るための datastore オブジェクトを作成します。

カスタム データストアを使用して独自のデータをプレビューし、順次処理向けに MATLAB® に読み取ります。

この例では簡単なデータ セットを使用して、カスタム データストアを使ったワークフローを説明します。このデータ セットは、15 個のバイナリ (.bin) ファイルの集合で、各ファイルには 1 列 (変数 1) 10000 行の符号なし整数 (レコード) が含まれます。

dir('*.bin')
binary_data01.bin  binary_data02.bin  binary_data03.bin  binary_data04.bin  binary_data05.bin  binary_data06.bin  binary_data07.bin  binary_data08.bin  binary_data09.bin  binary_data10.bin  binary_data11.bin  binary_data12.bin  binary_data13.bin  binary_data14.bin  binary_data15.bin  

関数 MyDatastore を使用して、datastore オブジェクトを作成します。MyDatastore の実装の詳細については、「データストアを作成してバイナリ ファイルを読み取る」の例を参照してください。

folder = fullfile('*.bin'); 
ds = MyDatastore(folder); 

データストアのデータをプレビューします。

preview(ds)
ans = 8x1 uint8 column vector

   113
   180
   251
    91
    29
    66
   254
   214

while ループでデータを読み取り、hasdata メソッドを使用してさらに読み取り可能なデータがあるかどうかをチェックします。

while hasdata(ds)
    data = read(ds);
    % do something
end

データストアを初期状態にリセットし、データストアの最初からデータを読み取ります。

reset(ds);
data = read(ds);

あるいは、データの集合がメモリに収まる場合は、データストア内のすべてのデータを読み取ります。このフォルダーには 15 個のファイルがあり、各ファイルに 10000 のレコードがあるため、出力サイズは 150000 のレコードになります。

dataAll = readall(ds);
whos dataAll
  Name              Size             Bytes  Class    Attributes

  dataAll      150000x1             150000  uint8              

カスタム datastore オブジェクトを作成し、Windows® マシンに保存してから、Linux® マシンで読み込んで処理します。

カスタム データストアを作成して保存する前に、異なるプラットフォームでのデータのルート パスを特定します。ルート パスはマシンまたはファイル システムによって異なります。たとえば、次のルート パスを使用してデータにアクセスするとします。

  • "Z:\DataSet" (ローカルの Windows マシン上)

  • "/nfs-bldg001/DataSet" (Linux クラスター上)

次に、AlternateFileSystemRoots プロパティを使用してこれらのルート パスを関連付けます。MyDatastore の実装の詳細については、Build Datastore to Read Binary Files の例を参照してください。

altRoots = ["Z:\DataSet","/nfs-bldg001/DataSet"];
ds = MyDatastore('Z:\DataSet\*.bin',altRoots);

データストア内のファイルを確認します。

fileTbl = resolve(ds.Fileset);
fileTbl.FileName
ans =

  12×1 cell array

    {'Z:\DataSet\binary_data01.bin'}
    {'Z:\DataSet\binary_data02.bin'}
    {'Z:\DataSet\binary_data03.bin'}
      .
      . 
      .

データストアを保存します。

save ds_saved_on_Windows.mat ds

Linux プラットフォームにデータストアを読み込んで、データストア内のファイルを確認します。ルート パス 'Z:\DataSet' は読み込み時に Linux クラスター上でアクセスできないため、データストア関数は AlternateFileSystemRoots プロパティで指定された値に基づいてルート パスを自動的に更新します。

load ds_saved_on_Windows.mat
fileTbl = resolve(ds.Fileset);
fileTbl.FileName
ans =

  12×1 cell array

    {'/nfs-bldg001/DataSet/binary_data01.bin'}
    {'/nfs-bldg001/DataSet/binary_data02.bin'}
    {'/nfs-bldg001/DataSet/binary_data03.bin'}
      .
      . 
      .
これで、Linux マシン上でこのデータストアを処理および解析できます。

バージョン履歴

R2017b で導入