我想知道是否有办法对一个矩阵的值进行操作,分别基于另一个矩阵的每一行的值,而不使用for
循环。
以下一个具体示例。
data
是一个~500k的行矩阵,有三列:第一列是小时/日期列表(我将它们作为序列号),每天24小时覆盖数年,第二列是一个位置ID,第三个是该地区的电费。
hours
有两列:第一列是日期/小时列表作为序列号,第二列是特定于该小时的特定上限。
我需要做的是,hours
中的每个日期和小时,找到低于hours
中设置的上限的最大电费成本,并保存相应的ID如果hours
是唯一的,则在id
的第三列中的位置;如果没有满足条件的位置或者多于一个的位置,则为零。
我正在使用的代码的简化版本:
#Add a third column for the hours matrix
ids=zeros(rows(hours),1)
hours=horzcat(hours,ids)
for i=1:rows(hour)
#Get the data for all locations in that hour
idx=(data(:,1)==hour(i,1) )
hourlydata=(data(idx,:))
#Get the ID for the maximum below the limit in that hour
idx=(hourlydata(:,3)<hour(i,2))
idlimit=(hourlydata(idx,3)==max(hourlydata(idx,3))
dataid=hourlydata(idlimit,2)
#Check if the data exists and is unique
if(rows(dataid)==1)
id=dataid(1,1)
else
id=0
endif
#Save the ID
hour(i,3)=id
endfor
有没有办法在不使用for
循环的情况下执行此操作?
(我已经优化了data
矩阵,使其尽可能小,但它仍然很大,所以在尝试实现解决方案时可能会遇到内存限制)
答案 0 :(得分:0)
您可以使用arrayfun。假设您的数据是
data = [datenum('2014-01-17'), 1, 13;datenum('2014-01-18'), 2, 7]
hours = [datenum('2014-01-17'), 17; datenum('2014-01-18'), 3]
然后定义选择器功能
function id = select( d, limit, data )
idx = (data(:,1)==d );
hourlydata = (data(idx,:));
idx = (hourlydata(:,3)<limit);
idlimit = (hourlydata(idx,3)==max(hourlydata(idx,3)));
dataid=hourlydata(idlimit,2);
if length(dataid)==1
id=dataid(1,1)
else
id=0
end
end
现在我们找到一个与包含id
的小时相同的向量arrayfun(@(d, limit) select(d, limit, data), hours(:,1), hours(:,2))
ans =
1
0
您可以轻松地将此向量合并数小时。
现在我怀疑这更快,但没有循环。与MATLAB一起使用,未使用Octave进行检查。