会感激一些指示。我正在阅读大约1M行数据,使用以下代码需要大约24小时。如何改善执行时间?
数组Day
包含从开始起n th 天的值,并且特定日期有多于一条记录。该程序检查特定ID(存储在unique_id
)是否在180天内重复。
%// calculating the number of repeats within 180 days
fid2 = 'data_050913/Unique_id_repeat_count1.xlsx';
fid1 = 'data_050913/data_050913_2000.csv';
fid_data = fopen(fid1);
data = fgetl(fid_data); %// the first line, title line
ep = 0; %// position point number
while 1
data = fgetl(fid_data);
if(length(data)<10)
break;
end
ep = ep+1;
id = find(data == ',');
unique_id(ep) = str2num(data(1:id(1)-1));
day(ep) = str2num(data(id(8)+1:id(9)-1));
end
repeat = zeros(ep,1);
tic
i = 1;
count = 0;
while i <= ep
j = i+1;
while ( (j<=ep) && (day(j)<= day(i)+179) )
if unique_id(i) == unique_id(j)
count = 1;
break;
end
j = j+1;
end
repeat(i,1) = count;
count = 0;
i = i+1;
end
toc
i = 1;
k = 1;
while i<=ep
count = repeat(i,1);
j=i;
while (day(j) == day(i))
count = repeat(j,1)+count;
j = j+1;
if j > ep
break;
end
end
day_final(k,1)= day(i);
repeat_final(k,1) = count;
k = k+1;
i = j;
end
xlswrite(fid2,day_final,'Repeat_Count','A2');
xlswrite(fid2,repeat_final,'Repeat_Count','B2');
由于
答案 0 :(得分:3)
如果尚未执行此操作,请确保尽可能预先分配所有内存。通过这样做,我已经看到Matlab脚本从24小时到8分钟。
使用zeros
函数为所有不断增长的数组(day
,unique_id
,repeat
,day_final
和repeat_final
预先分配内存。
x = zeros(1000); %// Creates a 1000 element array of all zeros
答案 1 :(得分:2)
以下代码的运行速度比原始代码快200倍,并且结果相同。
当然,加速取决于输入数据的分布,我的假设可能不正确(我有1000个唯一ID,平均每天19条记录)。
我还编写了一些代码来生成类似于我认为输入数据的数据。
% Generate Input data
ep = 100000;
isRepeatedDay = rand(1,ep) < 0.95;
day = cumsum(~isRepeatedDay);
unique_ids = 1:1000;
unique_id_indices = round(rand(ep,1)*length(unique_ids));
unique_id_indices(unique_id_indices < 1) = 1;
unique_id_indices(unique_id_indices > length(unique_id_indices) ) = length(unique_id_indices);
unique_id = unique_ids(unique_id_indices);
%Process the input data to find repeats
tic
repeat = zeros(ep,1);
[unique_values,~,indices] = unique(unique_id);
for uv_index = 1:length(unique_values)
uv = unique_values(uv_index);
uv_indices = find(indices == uv_index);
for i=1:length(uv_indices)-1
daysDifference = day(uv_indices(i+1)) - day(uv_indices(i));
if daysDifference <= 179
repeat(uv_indices(i),1) = 1;
end
end
end
toc
答案 2 :(得分:1)
如果unique_id
可以有许多不同的值(甚至可能没有),我会这样做。
我的系统上的操作时间不到5秒:
x = round(rand(1000000,1)*10);
result = zeros(size(x));
windowsize = 180;
for t = 1:(numel(x)-windowsize)
result(t) = sum(x(t+1:t+windowsize)==x(t));
end
我认为这就是你需要的,一定要检查你是否想要'向前'或'向后'。
答案 3 :(得分:1)
首先,我将向您展示逻辑索引的工作原理:
vector=[0 4 5 2 4]
logicalIndex=(vector==4) %the type of logicalIndex is bool!
excerpOfVector=vector(logicalIndex) %some other ways to use logial Indexing
excerpOfVectorSecondVariation=zeros(1,length(vector))
excerpOfVectorSecondVariation(logicalIndex)=vector(logicalIndex)
vector(vector < 5) = 11; %implicit use of logical indexing