2

1911518 個の値のデータセットがあります。テキストスキャン機能を使用しました。しかし、この関数は 1424458 個の値しか返しません。残りの値を取得するために再度新しい変数を作成しましたが、今回は約 9000 の値が得られました。この理由が何であるかを知っている人はいますか?

n=9
N=1911518

file_id=fopen('CRSP.csv');

C=textscan(file_id,'%s',n,'delimiter', ','); %To get the headers
C_text=textscan(file_id,'%s %s %s %d %d %d %d %f %f',N, 'delimiter' , ','); 

%Returns 1424458

C_text1=textscan(file_id,'%s %s %s %d %d %d %d %f %f',N, 'delimiter' , ','); 

%Returns only 9000 values    

fclose(file_id);

サンプルデータ

DATE,COMNAM,TICKER,PERMNO,PERMCO,SHROUT,VOL,RET,sprtrn

01/02/1996, ACME CLEVELAND CORP NEW, AMT, 10057, 20020, 6313, 23700,  0.000000,  0.007793
01/03/1996, ACME CLEVELAND CORP NEW, AMT, 10057, 20020, 6313, 20800,  0.020000,  0.000950
01/04/1996, ACME CLEVELAND CORP NEW, AMT, 10057, 20020, 6313, 65300, -0.026144, -0.005826
01/05/1996, ACME CLEVELAND CORP NEW, AMT, 10057, 20020, 6313, 340600, 0.000000, -0.001587
01/08/1996, ACME CLEVELAND CORP NEW, AMT, 10057, 20020, 6313, 3400,   0.000000,  0.002821
01/09/1996, ACME CLEVELAND CORP NEW, AMT, 10057, 20020, 6313, 27200, -0.006711, -0.014568
01/10/1996, ACME CLEVELAND CORP NEW, AMT, 10057, 20020, 6313, 25400, -0.033784, -0.018000
01/11/1996, ACME CLEVELAND CORP NEW, AMT, 10057, 20020, 6313, 14000,  0.000000,  0.007034
4

2 に答える 2

2

データにエラーがあるか、フォーマットパターンがデータと一致していないと思います。次の行を抽出してみてください。

file_id=fopen('CRSP.csv');
for idx=1:1424456
    fgetl(file_id); %dump data
end
for idx=1:10
    fprintf('%s\n',fgetl(file_id));
end

エラーがある場合は、印刷された 2 行目または 3 行目にあるはずです。何か特別なことはありますか?たぶん、COMNAMいくつかの特別なキャラクターがありますか?

ファイルを読み取るには、次のコードを使用して行ごとに読み取ります。

file_id=fopen('CRSP.csv');
line=fgetl(file_id);
data={};
int ix=1;
while(ischar(line))
    [parsed,sindex,eindex] = regexpi(line,'(\d\d/\d\d/\d\d\d\d)\s*, ([\w ]+), ([\w ]+), ([\d]+), ([\d]+), ([\d]+), ([\d]+), ([\d \.]+), ([\d \.]+)','tokens')
    if ~isempty(sindex)&&numel(sindex)==1&&(sindex==1)&&(eindex==numel(x))
        data{end+1}=parsed{1};
    else
        fprintf('Unable to parse line %d with content: %S',ix,line);
    end
    line=fgetl(file_id);
    ix=ix+1;
end

正規表現の簡単な要約:

'(...)' 間のすべてが返される「トークン」です

'([\d .]+)' 数字、空白、および "."

'([\d .]+)' 数字と空白

'([\w ]+)' 空白を含む単語

'(\d\d/\d\d/\d\d\d\d)' 日付

この表現は少し「怠け者」です。数値として「0.000」だけでなく、「0.0 00」も受け付けます。または他のいくつかの組み合わせですが、すべてのエラーを検出するには十分です。そうでない場合は、表現を改善する必要があります。

于 2013-10-18T20:50:32.160 に答える
1

Daniel Rの答えは基本的に正しいです。詳しく説明すると (これをコメントとして投稿したはずですが、評判がありません)、textscanMATLAB は非常に扱いにくく、指定した形式と正確に一致しないものにヒットすると、基本的に救済されます。

エラーや不整合が含まれている可能性が高いデータファイルがある場合、主なオプションは、ファイルを何らかの方法で前処理してそれらのエラーを取り除くか、(Daniel が示唆するように) 自分でファイルを 1 行ずつ読み取って解析することです。それはあなたが望むが。前者は、手動で行う予定がなく、修正するエラーが多くない場合を除いて、おそらく後者と同じくらい多くの作業が必要になるため、ほとんどの場合、独自のパーサーを作成する方が簡単です。

あなたが潜在的にできる唯一の他のこと - 唯一のエラーがタイプのエラーである場合(たとえば、列は整数であると想定されていますが、浮動小数点数がスリップすることがあります)、 textscan を使用してフォーマット指定子をより多くのものに置き換えることができます一般的なもの。%dたとえば、その例では、 (整数) を%f(浮動小数点数)に置き換えることができます。すべての整数は浮動小数点数であるため、問題なく動作するはずです。最も極端なケースでは、すべての列を文字列 ( %s) として読み取ることができますが、とにかくそれらをすべて解析する必要があり、おそらくtextscan.

于 2013-10-18T22:30:30.970 に答える