我有一个大矩阵(30000 x 500),一列表示未来3年的每小时数据,每列是不同的情况,即我有500个价格情景,其中一行中的每个单元格具有相同的时间戳 .
我需要在时间轴上聚合这个,所以如果每天我需要制作一个(30000 / nrdays x 500)的矩阵,如果每月(30000 / nrmonths x 500)并且显然也保持正确的日期 .
在matlab中,我创建了一个索引,每天或每个月都有一个唯一的编号,然后使用以下内容循环遍历列:
accumarray(idx,price(:,i),[numel(unique(idx)) 1], @mean)
如果我想在c#中这样做,最好的方法是什么?
以下是我到目前为止:
public class matrixwihtdates
{
public DateTime dats;
public ILArray nums;
}
public class endres
{
public string year;
public string month;
public string day;
public ILArray nums;
}
public static List aggrmatrix(ILArray origmatrix, DateTime std, DateTime edd)
{
var aggrmatr = new List();
for (int i = 0; i < origmatrix.Length; i++)
{
aggrmatr.Add(new matrixwihtdates
{
dats = std.AddHours(i),
nums = origmatrix[i, "full"],
});
}
return aggrmatr.GroupBy(a => new { yr = a.dats.Year, mt = a.dats.Month })
.Select(g => new endres {
year = g.Key.yr.ToString(),
month = g.Key.mt.ToString(),
nums = ILMath.mean(g.Select(a => a.nums).ToArray(),1) }).ToList();
}
关键问题是我不知道如何对LINQ语法中的每个列进行平均,以便返回向量(1x500) . 或者我应该不使用LINQ?我上面的最后一行不起作用 .
UPDATE:
我添加了一个没有LINQ的更强大的版本,这似乎工作但仍然有点笨拙 .
public static List> aggrmatrixImp(ILArray origmatrix, DateTime std)
{
List> aggrmatr = new List>();
ILArray tempmatrix;
int startindicator = 0;
int endindicator = 0;
int month = std.Month;
for (int i = 0; i < origmatrix.Length; i++)
{
if (std.AddHours(i).Month != month)
{
endindicator = i - 1;
tempmatrix = origmatrix[ILMath.r(startindicator, endindicator), ILMath.r(0, ILMath.end)];
aggrmatr.Add(ILMath.mean(tempmatrix, 1));
startindicator = i;
month = std.AddHours(i).Month;
}
}
return aggrmatr;
}
我仍然想让LINQ版本工作 .
Update 2
我考虑了Haymo的建议,这是另一个版本,速度是原来的两倍 .
public static ILArray aggrmatrixImp2(ILArray origmatrix, DateTime firstdateinfile, DateTime std, DateTime edd)
{
int nrmonths = ((edd.Year - std.Year) * 12) + edd.Month - std.Month;
ILArray aggrmatr = ILMath.zeros(nrmonths,500);
int startindicator = std.Date.Subtract(firstdateinfile.Date).Duration().Days*24;
int endindicator = 0;
DateTime tempdate = std.AddMonths(1);
tempdate = new DateTime(tempdate.Year, tempdate.Month, 1);
for (int i = 0; i < nrmonths; i++)
{
endindicator = tempdate.Date.Subtract(std.Date).Duration().Days * 24-1;
aggrmatr[i, ILMath.full] = ILMath.mean(origmatrix[ILMath.r(startindicator, endindicator), ILMath.full], 1);
tempdate = tempdate.AddMonths(1);
startindicator = endindicator+1;
}
return aggrmatr;
}
我没有工作的LINQ版本,但我怀疑它会更快 .