这与我之前提出的问题相似,但略有不同:
所以我在matlab中有一个非常大的结构数组。假设,为了论证,为了简化情况,假设我有类似的东西:
structure(1).name, structure(2).name, structure(3).name structure(1).returns, structure(2).returns, structure(3).returns(在我的真实程序中,我有 647 个结构)
进一步假设 structure(i).returns 是一个向量(非常大的向量,大约 2,000,000 个条目),并且出现了一个条件,我想从 structure(i).returns 中删除所有 i 的第 j 个条目。你怎么做到这一点?或者更确切地说,您如何合理快速地做到这一点?我已经尝试了一些东西,但它们都非常慢(我将在一秒钟内展示它们)所以我想知道社区是否知道更快的方法来做到这一点。
我以两种不同的方式解析了我的数据;第一种方法将所有内容都保存为单元格数组,但由于对我来说效果不佳,我再次解析数据并将所有内容都放置为向量。
我实际上在做的是尝试删除 NaN 数据,以及我的数据文件的同一相应行中的所有数据,然后在应用 Hampel 过滤器后做同样的事情。在此尝试中,我的代码的相关部分是:
for i=numStock+1:-1:1
for j=length(stock(i).return):-1:1
if(isnan(stock(i).return(j)))
for k=numStock+1:-1:1
stock(k).return(j) = [];
end
end
end
stock(i).return = sort(stock(i).return);
stock(i).returnLength = length(stock(i).return);
stock(i).medianReturn = median(stock(i).return);
stock(i).madReturn = mad(stock(i).return,1);
end;
for i=numStock:-1:1
for j = length(stock(i+1).volume):-1:1
if(isnan(stock(i+1).volume(j)))
for k=numStock:-1:1
stock(k+1).volume(j) = [];
end
end
end
stock(i+1).volume = sort(stock(i+1).volume);
stock(i+1).volumeLength = length(stock(i+1).volume);
stock(i+1).medianVolume = median(stock(i+1).volume);
stock(i+1).madVolume = mad(stock(i+1).volume,1);
end;
for i=numStock+1:-1:1
for j=stock(i).returnLength:-1:1
if (abs(stock(i).return(j) - stock(i).medianReturn) > 3*stock(i).madReturn)
for k=numStock+1:-1:1
stock(k).return(j) = [];
end
end;
end;
end;
for i=numStock:-1:1
for j=stock(i+1).volumeLength:-1:1
if (abs(stock(i+1).volume(j) - stock(i+1).medianVolume) > 3*stock(i+1).madVolume)
for k=numStock:-1:1
stock(k+1).volume(j) = [];
end
end;
end;
end;
但是,这会返回错误:
“矩阵索引超出删除范围。
失败错误(第 110 行)stock(k).return(j) = [];"
因此,我尝试将所有内容解析为向量。然后我决定在构建结构数组之前尝试删除向量中的适当条目。这不会返回错误,但速度很慢:
%% Delete bad data, Hampel Filter
% Delete bad entries
id=strcmp(returns,'');
returns(id)=[];
volume(id)=[];
date(id)=[];
ticker(id)=[];
name(id)=[];
permno(id)=[];
sp500(id) = [];
id=strcmp(returns,'C');
returns(id)=[];
volume(id)=[];
date(id)=[];
ticker(id)=[];
name(id)=[];
permno(id)=[];
sp500(id) = [];
% Convert returns from string to double
returns=cellfun(@str2double,returns);
sp500=cellfun(@str2double,sp500);
% Delete all data for which a return is not a number
nanid=isnan(returns);
returns(nanid)=[];
volume(nanid)=[];
date(nanid)=[];
ticker(nanid)=[];
name(nanid)=[];
permno(nanid)=[];
% Delete all data for which a volume is not a number
nanid=isnan(volume);
returns(nanid)=[];
volume(nanid)=[];
date(nanid)=[];
ticker(nanid)=[];
name(nanid)=[];
permno(nanid)=[];
% Apply the Hampel filter, and delete all data corresponding to
% observations deleted by the filter.
medianReturn = median(returns);
madReturn = mad(returns,1);
for i=length(returns):-1:1
if (abs(returns(i) - medianReturn) > 3*madReturn)
returns(i) = [];
volume(i)=[];
date(i)=[];
ticker(i)=[];
name(i)=[];
permno(i)=[];
end;
end
medianVolume = median(volume);
madVolume = mad(volume,1);
for i=length(volume):-1:1
if (abs(volume(i) - medianVolume) > 3*madVolume)
returns(i) = [];
volume(i)=[];
date(i)=[];
ticker(i)=[];
name(i)=[];
permno(i)=[];
end;
end
正如我所说,这很慢,可能是因为我在一个非常大的数据集上使用了 for 循环;但是,我不确定其他人会如何做到这一点。很抱歉这篇巨大的帖子,但有没有人建议我如何以合理的方式去做我所要求的事情?
编辑:我应该补充一点,让向量方法工作可能更可取,因为我的目标是将所有返回向量放入一个矩阵并将所有体积向量放入一个矩阵并对它们执行 PCA,我不知道我会如何使用单元阵列(或者即使 princomp 可以在单元阵列上工作)。
EDIT2:我已经更改了代码以符合您的建议(尽管我确实决定放弃速度并保持 for 循环以保持结构数组,因为重新解析这些数据在时间上会更糟)。新的代码片段是:
stock_return = zeros(numStock+1,length(stock(1).return));
for i=1:numStock+1
for j=1:length(stock(i).return)
stock_return(i,j) = stock(i).return(j);
end
end
stock_return = stock_return(~any(isnan(stock_return)), : );
这会返回一个索引超出矩阵尺寸错误,我不知道为什么。有什么建议么?