6

文字列と double の混合型の大量の表形式データを処理する必要があります。標準的な問題だと思います。これを扱うためのMatlabの最良のデータ構造は何ですか?

Cellarray は間違いなく答えではありません。非常にメモリ効率が悪いです。(以下に示すテスト)。データセット (統計ツールボックスから) は時間と空間の効率が非常に悪いです。それは私に structarray または配列の構造体を残します。以下の時間とメモリの両方について、4つの異なるオプションすべてでテストを行いましたが、私がテストしたものには配列の構造体が最適なオプションであるように思えます。

私はMatlabに比較的慣れていないので、率直に言って、これは少し残念です。とにかく、何かが足りないかどうか、またはテストが正確/合理的かどうかについてのアドバイスを探しています。アクセス/変換/メモリ使用量以外に、このようなものを使用してより多くのコードを作成するときに発生する可能性がある他の考慮事項が欠けていますか? (ちなみにR2010bを使用しています)

* *テスト #1: アクセス速度 データ項目へのアクセス。

cellarray:0.002s
dataset:36.665s       %<<< This is horrible
structarray:0.001s
struct of array:0.000s

* *テスト 2: 変換速度とメモリ使用量 このテストからデータセットを削除しました。

Cellarray(doubles)->matrix:d->m: 0.865s
Cellarray(mixed)->structarray:c->sc: 0.268s
Cellarray(doubles)->structarray:d->sd: 0.430s
Cellarray(mixed)->struct of arrays:c->sac: 0.361s
Cellarray(doubles)->struct of arrays:d->sad: 0.887s
  Name           Size               Bytes  Class     Attributes
    c         100000x10            68000000  cell                
    d         100000x10            68000000  cell                
    m         100000x10             8000000  double              
    sac            1x1             38001240  struct              
    sad            1x1              8001240  struct              
    sc        100000x1             68000640  struct              
    sd        100000x1             68000640  struct  

================== コード: テスト#1

  %% cellarray
  c = cell(100000,10);
  c(:,[1,3,5,7,9]) = num2cell(zeros(100000,5));
  c(:,[2,4,6,8,10]) = repmat( {'asdf'}, 100000, 5);
  cols = strcat('Var', strtrim(cellstr(num2str((1:10)'))))';
  te = tic;
  for iii=1:1000
      x = c(1234,5);
  end
  te = toc(te);
  fprintf('cellarray:%0.3fs\n', te);
  %% dataset
  ds = dataset( { c, cols{:} } );
  te = tic;
  for iii=1:1000
      x = ds(1234,5);
  end
  te = toc(te);
  fprintf('dataset:%0.3fs\n', te);
  %% structarray
  s = cell2struct( c, cols, 2 );
  te = tic;
  for iii=1:1000
      x = s(1234).Var5;
  end
  te = toc(te);
  fprintf('structarray:%0.3fs\n', te);
  %% struct of arrays
  for iii=1:numel(cols)
      if iii/2==floor(iii/2) % even => string
          sac.(cols{iii}) = c(:,iii);
      else
          sac.(cols{iii}) = cell2mat(c(:,iii));
      end
  end
  te = tic;
  for iii=1:1000
      x = sac.Var5(1234);
  end
  te = toc(te);
  fprintf('struct of array:%0.3fs\n', te);

================== コード: テスト #2

%% cellarray
% c - cellarray containing mixed type 
c = cell(100000,10);
c(:,[1,3,5,7,9]) = num2cell(zeros(100000,5));
c(:,[2,4,6,8,10]) = repmat( {'asdf'}, 100000, 5);
cols = strcat('Var', strtrim(cellstr(num2str((1:10)'))))';
% c - cellarray containing doubles only
d = num2cell( zeros( 100000, 10 ) );
%% matrix
% doubles only
te = tic;
m = cell2mat(d);
te = toc(te);
fprintf('Cellarray(doubles)->matrix:d->m: %0.3fs\n', te);
%% structarray
% mixed
te = tic;
sc = cell2struct( c, cols, 2 );
te = toc(te);
fprintf('Cellarray(mixed)->structarray:c->sc: %0.3fs\n', te);
% doubles
te = tic;
sd = cell2struct( d, cols, 2 );
te = toc(te);
fprintf('Cellarray(doubles)->structarray:d->sd: %0.3fs\n', te);
%% struct of arrays
% mixed
te = tic;
for iii=1:numel(cols)
    if iii/2==floor(iii/2) % even => string
        sac.(cols{iii}) = c(:,iii);
    else
        sac.(cols{iii}) = cell2mat(c(:,iii));
    end
end
te = toc(te);
fprintf('Cellarray(mixed)->struct of arrays:c->sac: %0.3fs\n', te);
% doubles
te = tic;
for iii=1:numel(cols)
    sad.(cols{iii}) = cell2mat(d(:,iii));
end
te = toc(te);
fprintf('Cellarray(doubles)->struct of arrays:d->sad: %0.3fs\n', te);
%% 
clear iii cols te;
whos
4

2 に答える 2

1

大量のデータを管理する必要がある場合、MATLAB は最初から最適な選択ではないと思います。適切なデータベースを探して、最終的に必要なデータを MATLAB にインポートします。

ただし、とにかく MATLAB を使用することを計画している場合でも、 cellarraysを選択します。つまり、構造体のようにフィールド名の形式でデータへの構文参照が必要ない場合です。

cellarray を使用する場合は、各セルが 112 バイトのオーバーヘッドを課すことに注意してください。したがって、各列のセルを作成します (各スカラー double のセルではありません)。

c = cell(1,10);
c(1,1:2:10) = num2cell(rand(1e5,5),1);
c(1,2:2:10) = {cellstr(repmat('asdf', 100000, 1))};

およびメモリ単位(時間の変更なし):

Name           Size               Bytes  Class    Attributes
c              1x10            38000600  cell   

また、配列の構造体と呼ばれるものは、通常、構造体配列 (または非スカラー構造) とは対照的に、「スカラー」構造で参照されます。

私の記憶が正しければ、フィールドのネストを開始すると、構造体の読み取り/書き込みのパフォーマンスが低下する傾向があります (ただし、特定のスレッドを見つける必要があります)。

于 2013-04-27T00:23:20.620 に答える