我想知道是否有一种方法可以在不使用for
循环的情况下,根据另一个矩阵中每一行的值分别对一个矩阵的值进行运算。
下面是一个具体的例子。
data
是一个约500k的行矩阵,有三列:第一列是几年来每天24小时的小时/日期列表(我把它们作为序列号),第二列是位置ID,第三列是该位置的电费。
hours
有两列:第一列是作为序列号的日期/小时列表,第二列是特定于该小时的特定上限。
我需要做的是,对于hours
中的每个日期和小时,找到低于hours
中设置的上限的电气成本的最大值,如果id
是唯一的,则将相应位置的ID保存在hours
的第三列中,如果没有满足条件的位置或有多个位置,则将其保存为零。
我正在使用的代码的一个症状化版本:
#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
矩阵,使其尽可能小,但它仍然很大,所以在尝试实现解决方案时可能会遇到内存限制)
您可以使用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进行检查。