MATLAB:使用文本扫描并在矩阵中转换单元格数组

sas*_*ent 4 csv arrays matlab cell textscan

我有一个大的csv文件(应该是大约100万行),其中包含具有以下结构的选项数据(内容被更改):

secid, date, days, delta, impl_volatility, impl_strike, impl_premium, dispersion, cp_flag, ticker, index_flag, industry_group
100000, 02/05/1986, 60, -80, 0.270556, 74.2511, 5.2415, 0.021514, C, ASC, 0, 481
100000, 03/05/1986, 30, -40, 0.251556, 74.2571, 6.2415, 0.025524, P, ASC, 0, 481
Run Code Online (Sandbox Code Playgroud)

我使用以下方法成功导入了测试文件:

ftest = fopen('test.csv');
C = textscan(ftest,'%f %s %f %f %f %f %f %f %s %s %f %f','Headerlines',1,'Delimiter',',');
fclose(ftest);
Run Code Online (Sandbox Code Playgroud)

但是,C是一个单元格数组,这使得在matlab中处理文件内容变得更加困难.将它作为"常规"数组更容易(原谅我不知道正确的命名法,我刚开始使用matlab).

如果我输出C,我得到:

Columns 1 through 6
[2x1 double]    {2x1 cell}    [2x1 double]    [2x1 double]    [2x1 double]    [2x1 double]
Columns 7 through 12
[2x1 double]    [2x1 double]    {2x1 cell}    {2x1 cell}    [2x1 double]    [2x1 double]
Run Code Online (Sandbox Code Playgroud)

因此在C单元格数组中,有数组和单元格数组 - 数字数组和字符串数组.如果我尝试检查元素(1,2),我必须使用C {1}(2),但如果我想检查元素(2,2),我必须使用C {2} {2}.理想情况下,我想同时访问C(1,2)和C(2,2).问题是,我该怎么做?

我已经搜索了解决方案并找到了cells2mat,但只有当所有内容都是数字时(我认为)它才有效.我找到了这个解决方案:将单元格数组的单元格数组转换为矩阵矩阵,但是horzcat检索错误,我认为可能由于同样的问题而发生错误.

提前谢谢您的时间.

Rod*_*uis 5

由于你有一个包含数字和字符数据的数组,你想要的是不可能的(相信我,它也是不切实际的).

引用数字数组中的单个数字与引用整个字符串不同.根本就没有逃避,也不应该:你对待鲜花与对待人们的方式不同(我当然希望如此).

在MATLAB中,字符串是普通数组,不同之处在于数组的每个条目都不代表数字,而是字符.引用单个字符与引用数组中的数字相同:

>> a = 'my string'
>> a(4)
ans = 
s
>> a+0  % cast to double to show the "true character" of strings
ans =
    109   121    32   115   116   114   105   110   103
Run Code Online (Sandbox Code Playgroud)

然而,textscan假设(这是理所当然的),你不想做,而是要提取整个字符串从文件.并且应该以不同的方式引用整个字符串,以表示您指的是整个字符串而不是单个字符.

我认为如果将结果从textscan一个普通的数字数组和一个字符串的单元格数组中分离出来,你会发现它更加直观,如下所示:

% load the data
ftest = fopen('test.csv');
C = textscan(ftest,...
    '%f %s %f %f %f %f %f %f %s %s %f %f',...     
    'collectoutput', true,...
    'Delimiter',',\n');
fclose(ftest);

% split into numeric and char arrays
numeric = [C{[1 3 5]}]
alpha   = [C{[2 4]}]
Run Code Online (Sandbox Code Playgroud)

numeric然后引用数据遵循与任何普通数组相同的规则,然后引​​用字符串alpha遵循正常的单元格引用规则(如alpha{2,1}获取'03/05/1986')

编辑基于没有您的意见,您想要进行如下转换:

% Read the data
fid = fopen('test.csv', 'r');
C = textscan(fid,...
    '%f %s %f %f %f %f %f %f %s %s %f %f',...
    'Headerlines', 1,...
    'Delimiter',',');
fclose(fid);

% Delete 10th element ('ASC')
C(10) = [];

% Mass-convert dates to datenums
C{2} = datenum(C{2}, 'dd/mm/yyyy');

% Map 'P' to 1 and 'C' to 2
map('PC') = [1 2];
C{9} = map([C{9}{:}]).';

% Convert whole array to numeric array
C = [C{:}];
Run Code Online (Sandbox Code Playgroud)