在MATLAB中使用`textscan`从csv文件中读取数据

时间:2016-12-31 21:52:07

标签: matlab csv import

[已编辑:]我有一个文件data2007a.csv,我将第一个连续的几行复制并粘贴(使用MacBook中的TextEdit)到新文件datatest1.csv进行测试:

Nomenclature,ReporterISO3,ProductCode,ReporterName,PartnerISO3,PartnerName,Year,TradeFlowName,TradeFlowCode,TradeValue in 1000 USD
S3,ABW,0,Aruba,ANT,Netherlands Antilles,2007,Export,6,448.91
S3,ABW,0,Aruba,ATG,Antigua and Barbuda,2007,Export,6,0.312
S3,ABW,0,Aruba,CHN,China,2007,Export,6,24.715
S3,ABW,0,Aruba,COL,Colombia,2007,Export,6,95.885
S3,ABW,0,Aruba,DOM,Dominican Republic,2007,Export,6,11.432

我想使用textscan将其读入MATLAB,仅使用第2,3,5列(从第二行开始)并编写以下代码

clc,clear all
fid = fopen('datatest1.csv');
data = textscan(fid,'%*s %s %d %*s %s %*[^\n]',...
       'Delimiter',',',...
       'HeaderLines',1);
fclose(fid);

但我最后只得到第2,3和5列的第二行:

enter image description here

然后我将第一行保留在data2007a.csv中,并选择其他几个保存为datatest2.csv

Nomenclature,ReporterISO3,ProductCode,ReporterName,PartnerISO3,PartnerName,Year,TradeFlowName,TradeFlowCode,TradeValue in 1000 USD
S3,ABW,1,Aruba,USA,United States,2007,Export,6,1.392
S3,ABW,1,Aruba,VEN,Venezuela,2007,Export,6,5633.157
S3,ABW,2,Aruba,ANT,Netherlands Antilles,2007,Export,6,310.734
S3,ABW,2,Aruba,USA,United States,2007,Export,6,342.42
S3,ABW,2,Aruba,VEN,Venezuela,2007,Export,6,63.722
S3,AGO,0,Angola,DEU,Germany,2007,Export,6,105.334
S3,AGO,0,Angola,ESP,Spain,2007,Export,6,8533.125

我写道:

clc,clear all
fid = fopen('datatest2.csv');
data = textscan(fid,'%*s %s %d %*s %s %*[^\n]',...
       'Delimiter',',',...
       'HeaderLines',1);
fclose(fid);  
data{1}

它完全符合我的要求:
enter image description here enter image description here

当我对原始数据文件data2007a.csv使用相同的代码时,它与第一种情况一样。

出了什么问题,我该如何解决?

[添加:]如果复制我的实验 1 ,可以发现两种情况都有效且问题不存在!我真的不知道发生了什么。

1 对于“复制”,我的意思是复制并粘贴上面给出的数据并将其另存为两个新文件,例如datatest4a.csvdatatest4b.csv。我使用visdiff('datatest1.csv', 'datatest4a.csv')来比较两个文件并返回:

  

enter image description here

1 个答案:

答案 0 :(得分:1)

考虑到你如何修复它,我认为这是一个行尾字符问题。在Windows和基于Unix的系统之间移动文本文件时,有时会出现这种情况,因为它们使用不同的约定。

Config添加到%*[^\n]格式的末尾时,就像在此处一样。它意味着跳过一切到最后。但是如果它期望一个特定的行尾字符,并且找不到它,它将跳过文件的末尾的所有内容。这可以解释为什么你正确读取一行,然后没有别的。

如果你没有指定行尾字符是什么,那么Matlab似乎默认为......某些东西......在帮助中这个不太明确的规范中:

  

默认的行尾序列是\ n,\ r或\ r \ n,具体取决于文件的内容。

尝试解决此问题而无需创建新文件的一种方法是将此textscan添加到'EndOfLine', '\r\n'来电:

  

如果你指定' \ r \ n',那么textscan会处理\ r,\ n和\ n中的任何一个   两者的组合(\ r \ n)作为行尾字符。

这有望处理大多数标准(ish)EOL约定。使用与最初用于创建文件的软件不同的软件进行复制粘贴和保存可能会改变行尾字符,以便Matlab能够识别它们。