8

後で参照できるように、出力を CSV ファイルに保存するスクリプトを作成しましたが、データをインポートするための 2 番目のスクリプトは、データを読み戻すのに非常に時間がかかります。

データの形式は次のとおりです。

Item1,val1,val2,val3
Item2,val4,val5,val6,val7
Item3,val8,val9

ここで、ヘッダーは一番左の列にあり、データ値は行の残りを占めます。大きな問題の 1 つは、データ値の配列の長さがテスト項目ごとに異なる可能性があることです。構造体として保存しますが、MATLAB がインストールされていないコンピューターで不良データの行を削除する必要がある場合があるため、MATLAB 環境の外で編集できるようにする必要があります。本当に、私の質問のパート 1 は次のとおりです。データを別の形式で保存する必要がありますか?

質問の 2 番目の部分: importdatacsvread、およびdlmreadを試しましたが、どれが最適か、またはより良い解決策があるかどうかはわかりません。現在、ループとfgetlを使用して独自のスクリプトを使用していますが、大きなファイルでは非常に遅くなります。助言がありますか?

function [data,headers]=csvreader(filename); %V1_1
 fid=fopen(filename,'r');
 data={};
 headers={};
 count=1;
 while 1
      textline=fgetl(fid);
      if ~ischar(textline),   break,   end
      nextchar=textline(1);
      idx=1;
      while nextchar~=','
        headers{count}(idx)=textline(1);
        idx=idx+1;
        textline(1)=[];
        nextchar=textline(1);
      end
      textline(1)=[];
      data{count}=str2num(textline);
      count=count+1;
 end
 fclose(fid);

(これはおそらくひどく書かれたコードであることはわかっています。私はエンジニアであり、プログラマーではありません。怒鳴らないでください。ただし、改善のための提案は大歓迎です。)

4

4 に答える 4

10

NaN最初のスクリプトでファイルを作成するときにファイルに値を埋め込むことができれば、おそらくデータが読みやすくなります。

Item1,1,2,3,NaN
Item2,4,5,6,7
Item3,8,9,NaN,NaN

または、空のフィールドを印刷することもできます。

Item1,1,2,3,
Item2,4,5,6,7
Item3,8,9,,

もちろん、適切にパディングするには、すべてのアイテムの値の最大数を事前に知っておく必要があります。上記のいずれかの形式で、たとえばTEXTSCANなどの標準のファイル読み取り関数の1つを使用できます。

>> fid = fopen('uneven_data.txt','rt');
>> C = textscan(fid,'%s %f %f %f %f','Delimiter',',','CollectOutput',1);
>> fclose(fid);
>> C{1}

ans = 

    'Item1'
    'Item2'
    'Item3'

>> C{2}

ans =

     1     2     3   NaN  %# TEXTSCAN sets empty fields to NaN anyway
     4     5     6     7
     8     9   NaN   NaN
于 2010-01-11T18:28:39.750 に答える
3

文字列のテキスト行を一度に 1 文字ずつ解析する代わりに。たとえば、strtokを使用して文字列を分割できます

stringParts = {};
tline = fgetl(fid);
if ~ischar(tline), break, end
i=1;
while 1
    [stringParts{i},r]=strtok(tline,',');
    tline=r;
    i=i+1;
    if isempty(r), break; end
end

% store the header
headers{count} = stringParts{1};

% convert the data into numbers
for j=2:length(stringParts)
    data{count}(j-1) = str2double(stringParts{j});
end
count=count+1;
于 2010-01-11T18:33:59.820 に答える
1

Matlab での csv データの読み取りで同じ問題が発生しました。これに対するサポートがほとんどないことに驚きましたが、データのインポート ツールを見つけました。私はr2015bにいます。

[ホーム] タブの上部バーで、[データのインポート] をクリックし、読みたいファイルを選択します。次のようなアプリ ウィンドウが表示されます。

データのインポート ツールのスクリーンショット

[選択項目のインポート] の下に、[関数を生成] オプションがあります。これにより、空のセルを埋める方法や、出力データ構造をどうしたいかなど、さまざまなカスタマイズ オプションが提供されます。さらに、MathWorks によって作成されているため、おそらく最も高速な方法で csv ファイルを読み取ることができます。それは私のファイルではほとんど瞬時でした。

于 2016-08-15T19:46:28.753 に答える
0

Q1) 列の最大数がわかっている場合は、空のエントリを NaN で埋めることができます。また、すべての値が数値の場合、「Item#」列が本当に必要ですか? はいの場合、「#」のみを使用できるため、すべてのデータは数値です。

Q2) num を読む最速の方法。mex ファイルのないファイルからのデータは csvread です。csv ファイルで文字列を使用しないようにしていますが、必要に応じて csv2cell 関数を使用します。

http://www.mathworks.com/matlabcentral/fileexchange/20135-csv2cell

于 2010-01-11T19:18:00.710 に答える