c# - 为给定值查找最接近的值(顶部和底部)
问题描述
我有包含 Value 和 DateTime 的数据集以及另一个代表时间线的数据集。在这种情况下,时间线由相隔 15 分钟的舍入时间组成,但可以是 30 或 60 分钟......我想计算某些时间的线性插值。那些时间在另一个数据集中。
问题是如何找到最接近的时间和价值,即特定时间之间的时间?
这是我的实现:
class Program
{
static void Main(string[] args)
{
List<Items> items = Items.GetItems();
List<DateTime> dt = GenerateTimeLine(items[0].Time, items[items.Count - 1].Time, 15);
DateTime X1 = items[0].Time;
double Y1 = items[0].Value;
DateTime X2 = items[1].Time;
double Y2 = items[1].Value;
DateTime X = dt[0];
double newValue = LinearInterpolation(X.ToOADate(), X1.ToOADate(), X2.ToOADate(), Y1, Y2);
}
在上面,我知道开始时间和结束时间,但我想进行某种查询,每次查询 TimeLine 数据集并检查每次关闭时间,取值并插值
static double LinearInterpolation(double X, double X1, double X2, double Y1, double Y2)
{
if ((X2 - X1) == 0)
{
return (Y1 + Y2) / 2;
}
else
{
return Y1 + (X - X1) * (Y2 - Y1) / (X2 - X1);
}
}
private static List<DateTime> GenerateTimeLine(DateTime start, DateTime end, int interval)
{
List<DateTime> lstD = new List<DateTime>();
int res = interval / 2;
int mod = (interval / 2) % 2;
int sec = 0;
if (interval == 1)
sec = 30;
else if (interval == 0)
sec = 0;
var tempStart = start.AddMinutes(interval).AddSeconds(sec);
var tempEnd = end.AddMinutes(interval).AddSeconds(sec);
DateTime st = new DateTime(tempStart.Year, tempStart.Month, tempStart.Day, tempStart.Hour, (tempStart.Minute / interval) * interval, 0);
DateTime en = new DateTime(tempEnd.Year, tempEnd.Month, tempEnd.Day, tempEnd.Hour, (tempEnd.Minute / interval) * interval, 0);
lstD.Add(st);
while (st <= en)
{
st = st.AddMinutes(interval);
lstD.Add(st);
}
return lstD;
}
}
public class Items
{
public double Value { get; set; }
public DateTime Time { get; set; }
public static List<Items> GetItems()
{
string input =
"| 31 | 2019-03-10 20:39:15 |\n" +
"| 12 | 2019-03-10 20:44:16 |\n" +
"| 12 | 2019-03-10 20:51:16 |\n" +
"| 33 | 2019-03-10 21:08:44 |\n" +
"| 33 | 2019-03-10 21:09:16 |\n" +
"| 11 | 2019-03-10 21:24:17 |\n" +
"| 9 | 2019-03-10 21:36:18 |\n" +
"| 14 | 2019-03-10 21:50:18 |\n" +
"| 15 | 2019-03-10 22:09:19 |\n" +
"| 16 | 2019-03-10 22:24:19 |\n" +
"| 31 | 2019-03-10 22:39:20 |\n" +
"| 3 | 2019-03-10 22:54:20 |\n" +
"| 34 | 2019-03-10 23:09:21 |\n" +
"| 10 | 2019-03-10 23:24:20 |\n" +
"| 17 | 2019-03-10 23:39:22 |\n" +
"| 18 | 2019-03-10 23:54:23";
List<Items> items = new List<Items>();
string line = "";
StringReader reader = new StringReader(input);
while ((line = reader.ReadLine()) != null)
{
string[] lineArray = line.Split(new char[] { '|' }, StringSplitOptions.RemoveEmptyEntries);
Items newDate = new Items()
{
Value = int.Parse(lineArray[0]),
Time = DateTime.Parse(lineArray[1])
};
items.Add(newDate);
}
return items;
}
}
解决方案
我终于想通了,如果有人遇到类似问题,这里是代码
static void Main(string[] args)
{
List<Dates> dates = Dates.GetDates();
List<DateTime> lstTimeLine = GenerateTimeLine(dates[0].Time, dates[dates.Count-1].Time, 10);
List<Dates> lstInterpolated = new List<Dates>();
foreach(var itm in lstTimeLine)
{
var target = itm;
Console.WriteLine("############################ X = " + itm);
var smaller = dates.Last(x => x.Time <= target);
var bigger = dates.FirstOrDefault(x => x.Time >= target);
if (bigger == null)
bigger = smaller;
Console.WriteLine(smaller.ID + " " + smaller.Time + " " + smaller.Value);
Console.WriteLine(bigger.ID + " " + bigger.Time + " " + bigger.Value); }
}
可能有更好的解决方案,但这完全满足我想要的。
推荐阅读
- scala - ReactiveMongo 0.20.12-Play28 在启动时因 MatchError 崩溃:成功异常
- javascript - 无法将反应组件导入 gatsby 启动组件
- c# - 将句子开头的每个单词大写。一个字符串中的多个句子。视觉 C#
- botframework - 在 Teams Toolkit 中粘贴消息传递端点
- javascript - 为什么数组允许字符串作为 JavaScript 中的索引?
- reactjs - 登录系统的安全问题
- lazy-loading - angular - 如何在 Angular11 应用程序上将 ngx-translate 与共享模块和延迟加载模块一起使用
- javascript - 使用Anguler.js搜索时如何在搜索前隐藏数据并显示
- r - Shiny App中的不同行数错误
- angular - 我如何以角度获取 status_code 400