我有像下面这样的数据集,需要通过之前的非空"Price“值来推断所有空的"Price”值。这看起来很简单,因为我需要考虑更多的类别- Cat1,Cat2,DateG和TimeG -我有这个“价格”。
class DataLoad
{
public int DateG { get; set; }
public DateTime TimeG { get; set; }
public string Cat1 { get; set; }
public string Cat2 { get; set; }
public double? Price { get; set; }
public int? Volume { get; set; }
public static List<DataLoad> GetSomeData()
{
return new List<DataLoad>()
{
new DataLoad {Cat1 = "A", Cat2 = "A1", DateG = 20190601, TimeG = DateTime.Parse("00:11:00.0000000"), Price = null, Volume = 4209},
new DataLoad {Cat1 = "A", Cat2 = "A1", DateG = 20190602, TimeG = DateTime.Parse("12:22:00.0000000"), Price = 123.54, Volume = 2109},
new DataLoad {Cat1 = "A", Cat2 = "A2", DateG = 20190602, TimeG = DateTime.Parse("15:33:00.0000000"), Price = 213.44, Volume = 2119},
new DataLoad {Cat1 = "A", Cat2 = "A2", DateG = 20190605, TimeG = DateTime.Parse("20:31:00.0000000"), Price = null, Volume = 1134},
new DataLoad {Cat1 = "A", Cat2 = "A2", DateG = 20190605, TimeG = DateTime.Parse("21:33:00.0000000"), Price = null, Volume = 1824},
new DataLoad {Cat1 = "A", Cat2 = "A2", DateG = 20190605, TimeG = DateTime.Parse("21:34:00.0000000"), Price = 214.74, Volume = 1111},
new DataLoad {Cat1 = "A", Cat2 = "A2", DateG = 20190606, TimeG = DateTime.Parse("23:41:00.0000000"), Price = 223.64, Volume = 3456},
new DataLoad {Cat1 = "B", Cat2 = "B1", DateG = 20190512, TimeG = DateTime.Parse("11:41:00.0000000"), Price = 135.77, Volume = 1956},
new DataLoad {Cat1 = "B", Cat2 = "B1", DateG = 20190513, TimeG = DateTime.Parse("12:34:00.0000000"), Price = null, Volume = 3457},
new DataLoad {Cat1 = "B", Cat2 = "B2", DateG = 20190514, TimeG = DateTime.Parse("08:11:00.0000000"), Price = 123.54, Volume = 9873},
new DataLoad {Cat1 = "B", Cat2 = "B2", DateG = 20190514, TimeG = DateTime.Parse("15:21:00.0000000"), Price = null, Volume = 2890},
};
}
}
我想知道如何根据DateG,TimeG,Cat1和Cat2对数据集进行排序,然后应用一些逻辑,但我总是以一堆for循环结束,这使它变得过于复杂,并且我无法在最终获得所需的输出。
所需输出应如下填充价格所示(无论DateG、TimeG、Cat1、Cat2的顺序如何):
Cat1 = "A", Cat2 = "A1", DateG = 20190601, TimeG = DateTime.Parse("00:11:00.0000000"), Price = 123.54, Volume = 4209
Cat1 = "A", Cat2 = "A1", DateG = 20190602, TimeG = DateTime.Parse("12:22:00.0000000"), Price = 123.54, Volume = 2109
Cat1 = "A", Cat2 = "A2", DateG = 20190602, TimeG = DateTime.Parse("15:33:00.0000000"), Price = 213.44, Volume = 2119
Cat1 = "A", Cat2 = "A2", DateG = 20190605, TimeG = DateTime.Parse("20:31:00.0000000"), Price = 213.44, Volume = 1134
Cat1 = "A", Cat2 = "A2", DateG = 20190605, TimeG = DateTime.Parse("21:33:00.0000000"), Price = 213.44, Volume = 1824
Cat1 = "A", Cat2 = "A2", DateG = 20190605, TimeG = DateTime.Parse("21:34:00.0000000"), Price = 214.74, Volume = 1111
Cat1 = "A", Cat2 = "A2", DateG = 20190606, TimeG = DateTime.Parse("23:41:00.0000000"), Price = 223.64, Volume = 3456
Cat1 = "B", Cat2 = "B1", DateG = 20190512, TimeG = DateTime.Parse("11:41:00.0000000"), Price = 135.77, Volume = 1956
Cat1 = "B", Cat2 = "B1", DateG = 20190513, TimeG = DateTime.Parse("12:34:00.0000000"), Price = 135.77, Volume = 3457
Cat1 = "B", Cat2 = "B2", DateG = 20190514, TimeG = DateTime.Parse("08:11:00.0000000"), Price = 123.54, Volume = 9873
Cat1 = "B", Cat2 = "B2", DateG = 20190514, TimeG = DateTime.Parse("15:21:00.0000000"), Price = 123.54, Volume = 2890
有没有什么简单的方法可以在有/没有linq的情况下做到这一点。
发布于 2019-06-25 21:55:34
List<DataLoad> result =
DataLoad.GetSomeData()
.OrderByDescending(d => d.DateG)
.ThenByDescending(t => t.TimeG)
.ThenByDescending(c1 => c1.Cat1)
.ThenByDescending(c2 => c2.Cat2)
.ToList();
您想要的输出示例令人困惑,但是如果我预料到了您想要的,那么这个查询应该会有所帮助。
发布于 2019-06-26 07:07:54
Linq将为您提供性能最佳的方法。
DataLoad.GetSomeData()
.Where(x => x.Price == null)
.ToList()
.ForEach(x =>
{
x.Price = list.First(v => v.Cat1 == x.Cat1 &&
v.Cat2 == x.Cat2 &&
v.Price != null)
.Price;
});
如果您的数据已经被排序,当价格为空时,您可以根据先前的值执行索引select。另一个示例是使用带有递归和order by的本地函数:
var orderedList = GetSomeData()
.OrderBy(x => x.Cat1)
.ThenBy(x => x.Cat2)
.ThenBy(x => x.Price);
var result = orderedList.Select((e, i) =>
{
e.Price = e.Price ?? GetPrice(i);
return e;
});
double GetPrice(int index)
{
return orderedList.ElementAt(++index).Price
?? GetPrice(index);
}
使用相同的方法逻辑,您可以编写for循环来做同样的事情。
https://stackoverflow.com/questions/56754869
复制相似问题