如何使用引号之间的逗号读取具有某些值的逗号分隔数据
How to read comma-delimited data with some values using commas between quotes
我有一个数据文件,其中包含我试图读入 Octave 的逗号分隔数据。大多数数据都很好,但有些数据包括双引号之间的数字,这些数字在引号之间使用逗号。这是数据的示例部分:
.123,4.2,"4,123",700,12pie
.34,4.23,602,701,23dj
.4345,4.6,"3,623,234",700,134nfg
.951,68.5,45,699,4lkj
我一直在使用 textscan
来读取数据(因为混合了数字和字符串),指定逗号分隔符,这在大多数情况下都有效,但偶尔文件包含这些更大的整数在该专栏中散布的引号中。我之前能够在数据文件中找到其中一个引用的数字,因为我知道它会在哪里,但它并不漂亮:
sclose = textscan(fid, '%n %n', 1, 'delimiter', ',');
junk = fgetl(fid, 1);
junk = textscan(fid, '%s', 1, 'delimiter', '"');
junk = fgetl(fid, 1);
sopen = textscan(fid, '%n %s', 1, 'delimiter', ',');
我不关心该列中的数据,但因为它会改变大小并且有时包含引号和我想忽略的额外逗号,所以我正在努力研究如何 read/skip 它。关于如何处理它有什么建议吗?
这是我当前的(丑陋的)方法,该方法将列作为字符串读取,然后使用 strfind
检查字符串中的 "。如果它存在,则它读取另一个逗号分隔的字符串并重复检查直到找到关闭的 " 然后继续读取数据。
fid = fopen('sample.txt', 'r');
for k=1:4
expdata1(k, :) = textscan(fid, '%n %n %s', 1, 'delimiter', ','); #read first 3 data pts
qcheck = char(expdata1(k,3));
idx = strfind(qcheck, '"'); #look for "
dloc = ftell(fid);
for l=1:4
if isempty(idx) #if no " present, continue reading data
break
endif
dloc = ftell(fid); #save location so can return to next data point
expdata1(k, 3) = textscan(fid, '%s', 1, 'delimiter', ','); #if " present, read next comma segment and check for "
qcheck = char(expdata1(k,3));
idx = strfind(qcheck, '"');
endfor
fseek(fid, dloc);
expdata2(k, :) = textscan(fid, '%n %s', 1, 'delimiter', ',');
endfor
fclose(fid);
一定有更好的方法...
我看到上面有一个 matlab 标签,你使用的是 matlab textscan 还是 octave?
如果在 matlab 中,我建议使用 readmatrix or readtable.
另请注意,带引号的字符串的格式说明符是 %q
。这应该适用于两种语言,即使是 textscan
.
将您的示例数据放入 data.csv
,以下是可能的:
>> readtable("data.csv", 'Format','%f%f%q%d%s');
ans =
4×5 table
Var1 Var2 Var3 Var4 Var5
______ ____ _____________ ____ __________
0.123 4.2 {'4,123' } 700 {'12pie' }
0.34 4.23 {'602' } 701 {'23dj' }
0.4345 4.6 {'3,623,234'} 700 {'134nfg'}
0.951 68.5 {'45' } 699 {'4lkj' }
我有一个数据文件,其中包含我试图读入 Octave 的逗号分隔数据。大多数数据都很好,但有些数据包括双引号之间的数字,这些数字在引号之间使用逗号。这是数据的示例部分:
.123,4.2,"4,123",700,12pie
.34,4.23,602,701,23dj
.4345,4.6,"3,623,234",700,134nfg
.951,68.5,45,699,4lkj
我一直在使用 textscan
来读取数据(因为混合了数字和字符串),指定逗号分隔符,这在大多数情况下都有效,但偶尔文件包含这些更大的整数在该专栏中散布的引号中。我之前能够在数据文件中找到其中一个引用的数字,因为我知道它会在哪里,但它并不漂亮:
sclose = textscan(fid, '%n %n', 1, 'delimiter', ',');
junk = fgetl(fid, 1);
junk = textscan(fid, '%s', 1, 'delimiter', '"');
junk = fgetl(fid, 1);
sopen = textscan(fid, '%n %s', 1, 'delimiter', ',');
我不关心该列中的数据,但因为它会改变大小并且有时包含引号和我想忽略的额外逗号,所以我正在努力研究如何 read/skip 它。关于如何处理它有什么建议吗?
这是我当前的(丑陋的)方法,该方法将列作为字符串读取,然后使用 strfind
检查字符串中的 "。如果它存在,则它读取另一个逗号分隔的字符串并重复检查直到找到关闭的 " 然后继续读取数据。
fid = fopen('sample.txt', 'r');
for k=1:4
expdata1(k, :) = textscan(fid, '%n %n %s', 1, 'delimiter', ','); #read first 3 data pts
qcheck = char(expdata1(k,3));
idx = strfind(qcheck, '"'); #look for "
dloc = ftell(fid);
for l=1:4
if isempty(idx) #if no " present, continue reading data
break
endif
dloc = ftell(fid); #save location so can return to next data point
expdata1(k, 3) = textscan(fid, '%s', 1, 'delimiter', ','); #if " present, read next comma segment and check for "
qcheck = char(expdata1(k,3));
idx = strfind(qcheck, '"');
endfor
fseek(fid, dloc);
expdata2(k, :) = textscan(fid, '%n %s', 1, 'delimiter', ',');
endfor
fclose(fid);
一定有更好的方法...
我看到上面有一个 matlab 标签,你使用的是 matlab textscan 还是 octave?
如果在 matlab 中,我建议使用 readmatrix or readtable.
另请注意,带引号的字符串的格式说明符是 %q
。这应该适用于两种语言,即使是 textscan
.
将您的示例数据放入 data.csv
,以下是可能的:
>> readtable("data.csv", 'Format','%f%f%q%d%s');
ans =
4×5 table
Var1 Var2 Var3 Var4 Var5
______ ____ _____________ ____ __________
0.123 4.2 {'4,123' } 700 {'12pie' }
0.34 4.23 {'602' } 701 {'23dj' }
0.4345 4.6 {'3,623,234'} 700 {'134nfg'}
0.951 68.5 {'45' } 699 {'4lkj' }