4

我有一个带有以下结构的选项数据的大型 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

我已经使用以下内容成功导入了一个测试文件:

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

但是,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]

所以在 C 的元胞数组中,有数组和元胞数组——数字数组和字符串元胞数组。如果我尝试检查元素 (1,2),我必须使用 C{1}(2),但如果我想检查元素 (2,2),我必须使用 C{2}{2}。理想情况下,我想同时访问 C(1,2) 和 C(2,2)。问题是,我该怎么做?

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

提前感谢您的宝贵时间。

4

2 回答 2

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

但是,textscan假设(正确地)您不想这样做而是想从文件中提取整个字符串。并且应该以不同的方式引用整个字符串,以表明您的意思是整个字符串而不是单个字符。

textscan如果您将结果从up 拆分为一个普通的数值数组和一个字符串元胞数组,我认为您会发现它更加直观,如下所示:

% 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]}]

在 then 中引用数据numeric遵循与任何普通数组相同的规则,并且在alphathen 中引用字符串遵循正常的单元格引用规则(如alpha{2,1}to get '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{:}];
于 2013-07-15T13:26:53.550 回答
0

我遇到了同样的问题......我更喜欢二维单元阵列,以便于访问并利用内置的 matlab 排序功能。

这是另一种可能对您有用的解决方案(这就是 TMW 在导入工具中自动生成的代码中的做法)。它将数值数组转换为元胞数组,以便您可以将它们连接成二维矩阵。

C([1,3,4,5,6,7,8,11,12]) = cellfun(@(x) num2cell(x), C([1,3,4,5,6,7,8,11,12]),'UniformOutput', false);

C = [C{1:end}];
于 2017-11-22T21:15:13.750 回答