2013-10-18 57 views
2

我有一个1911518值的数据集。我已经使用了textscan功能。但该函数仅返回1424458个值。我再次创建了一个新变量来获得剩余的值,但是这次它给了我大约9000个值。有谁知道这可能是什么原因?无法使用TextScan一次性在Matlab中导入所有值

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 
+1

您需要提供一些示例数据,否则很难为您提供帮助;) – thewaywewalk

+0

我不知道上述示例将提供多少帮助:P – user2848498

+0

如果换行符不丢失,它将有所帮助。请编辑您的问题,并将数据和代码添加为“代码示例”。这将保留所有线路制动器。 – Daniel

回答

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。] +)'Numbers,white space and”。“

'([\ d。] +)' 数字和空格

'([\ W] +)' 字,包括空白

“(\ d \ d/\ d \ d/d \ d \ d \ d \ d)'日期

这个表达式有点“懒”。它不仅接受“0.000”作为数字,而且接受“0.0 00”。或其他一些组合,但它应该足以检测所有错误。否则,表达式必须改进。

+0

你是对的,在数据​​中有一些错误的值。例如sprrtn,有字符串值。但我认为只是将所有值提取到matlab中,然后检查NAs或infs – user2848498

+0

现在,我发现有错误值,我如何删除它们并存储剩余的值而不破坏顺序 – user2848498

+0

我更新了我的答案。使用textscan也可能有一个更简单的解决方案,但我只是习惯于正则表达式。 – Daniel

1

Daniel R的回答基本上是正确的。为了详细说明(我会张贴这个评论,但我缺乏声誉),在MATLAB中的textscan是非常挑剔的,它基本上保存了,每当它遇到一些不符合你指定的格式。

如果你有一个可能包含一些错误或不一致的数据文件,你的主要选择是以某种方式预处理文件以删除这些错误,或者(如Daniel建议)自己在线阅读文件不管你想要什么,都可以解析它。前者可能与后者差不多,除非你打算手动完成,并且没有太多的错误需要修复,所以在大多数情况下,编写自己的解析器可能会更容易。

你可能会做的唯一的其他事情 - 如果唯一的错误是类型错误(例如列应该是一个整数,但有时浮点数字滑入),你仍然可以使用textscan并替换具有更通用的格式说明符。例如,在那个例子中,你可以用%f(浮点数)替代%d(整数)。由于所有整数都是浮点数,所以应该可以正常工作。在最极端的情况下,您可以将所有列读作字符串(%s),但是无论如何您都需要解析它们,而且您可能更好地在没有textscan的情况下执行此操作。

+0

如何删除错误。你能帮助我解释如何摆脱有错误的列 – user2848498