我是C#的新手。我想知道如何在C#中以直观的方式进行以下计算。我应该如何阅读输入csv文件以方便所需的计算?我是否将csv读入列表,数组,数据表等?某些单元格中存在空值。由于我是C#的新手,如果您能提供一些示例,我们将不胜感激。谢谢。 :)
输入: 我有一个输入csv文件格式:
<p> // header: date, Y, X1, X2, X3, X4 </p>
<p> // value: yyyy-mm-dd, double, double, double, double, double </p>
所以我有Y和所有X的时间序列数据。对于每个不同的日期,我有很多Y和X行。
数据处理: 我想做以下事情:
对于每个不同的日期,计算Y和每个X之间的相关性.Y和X的长度可以在不同的日期有所不同。所以每个日期我都会有corr(Y,X1),corr(Y,X2),corr(Y,X3),corr(Y,X4)。
对于每个不同的日期,排序Y并获得每行的排名,例如
Y等级
10 1
50 4
20 2
30 3
获得等级后,它们用于计算单个数量,例如QUANTITY。 (每个不同的日期我将有一个数量的数量。)
输出: 在所有计算之后,我想将结果导出到另一个格式为:
的csv文件<p> // header: date, corr(Y, X1), corr(Y, X2), corr(Y,X3), corr(Y,X4), QUANTITY </p>
<p> // value: yyyy-mm-dd, double, double, double, double, double </p>
答案 0 :(得分:1)
好的,到此为止。首先,我使用一个名为CsvHelper
的Nuget包来处理你的解析。它非常易于使用和有效。但是出于举例的目的,我只是用逗号分隔每条记录。
我们假设您在路径string path = ...;
中有一个包含csv的文件。首先,我们解析CSV。
首先,既然你说可以有空值(虽然CSV解析器可以更好地处理这个),让我们来一个方法。
private static double? getDoubleOrNull(string text)
{
if(string.IsNullOrWhiteSpace(text))
return null;
else
return double.Parse(text);
}
现在我们可以进行实际的解析并使用该方法。
var records = System.IO.File.ReadAllLines(path)
.Skip(1) // the header
.Select(c =>
{
var fields = c.Split(',');
return new
{
Date = DateTime.Parse(fields[0]),
Y = getDoubleOrNull(fields[1]),
X1 = getDoubleOrNull(fields[2]),
X2 = getDoubleOrNull(fields[3]),
X3 = getDoubleOrNull(fields[4]),
X4 = getDoubleOrNull(fields[5]),
};
});
完成,好吧,现在我们按日期分组并找到结果。我不确定你想如何关联数据,所以我只假设存在object corr(IEnumerable<double?> Y, IEnumerable<double?> X)
函数。我还假设存在object getQuantity(IEnumerable<KeyValuePair<int, double?>> ys)
,其中键表示您显示的基于1的排名,值表示原始CSV中的Y
值。
var result = records.GroupBy(c => c.Date)
.Select(c => new
{
Date = c.Key,
corr1 = corr(c.Select(x => x.Y), c.Select(x => x.X1)),
corr2 = corr(c.Select(x => x.Y), c.Select(x => x.X2)),
corr3 = corr(c.Select(x => x.Y), c.Select(x => x.X3)),
corr4 = corr(c.Select(x => x.Y), c.Select(x => x.X4)),
quantity = getQuantity(c => c.OrderBy(x => x).Select((x, index) => new KeyValuePair<int, double>(index + 1, x)))
});
现在,我相信我们应该输出数据。这使得它变得相对简单。
using (StreamWriter writer = new StreamWriter(outputFile))
{
writer.WriteLine("date, corr(Y, X1), corr(Y, X2), corr(Y,X3), corr(Y,X4), QUANTITY");
foreach(var v in result)
{
writer.WriteLine(string.Join(",", v.Date.ToString("yyyy-MM-dd"), v.corr1, v.corr2, v.corr3, v.corr4, v.quantity));
}
}
当然,您希望添加大量错误检查。自从我在SO文本编辑器中完成所有这些操作后,我可能已经写了一两个错字,但是从中找出最终解决方案应该很容易。
答案 1 :(得分:0)
我不会尝试发明我自己的CSV解析器 - 当你不得不考虑&#34;逃脱时,做正确的事情是非常困难的。字符串,不同的字段分隔符(&#34 ;;&#34;!)等.pp。
我喜欢kbcsv库,它可以轻松读取csv并提供带有结果的数据表: