我有一个大型CSV文件(50000 * 25),它本质上是一个包含数字和字母数字字段的数据表。
我在代码项目中使用了Lumenworks的“A Fast CSV Reader”。 (链接http://www.codeproject.com/Articles/9258/A-Fast-CSV-Reader?msg=4600509#xx4600509xx)
我正在寻找以后使用数据的最有效方法,我将不得不对部分数据求和,平均等。
到目前为止我的代码:
static void Main()
{
// open the file "data.csv" which is a CSV file with headers
using (CsvReader csv =
new CsvReader(new StreamReader(@"c:\Temp\Extrinsic_Hourly.csv"), true))
{
int fieldCount = csv.FieldCount;
csv.SupportsMultiline = false;
List<string> filedata = new List<string>();
string[] headers = csv.GetFieldHeaders();
while (csv.ReadNextRecord())
{
for (int i = 0; i < fieldCount; i++)
{
//if (headers[i] == "PowerPrice")
filedata.Add(csv[i]);
}
}
File.WriteAllLines(@"c:\Temp\test.txt", filedata);
}
最后一行只是检查导入是否有效。这工作正常,而且相对较快,但现在我有这个庞大的列表,很难使用。如果我现在需要对第13列进行平均,那我就不知道如何做到这一点。
filedata.column(13).Average()
显然不起作用,尤其是因为它的所有字符串。
将更多结构化的数据导入类中,或者将大二维列表的整列转换为1d列表会更好,如果它们是数字的话,我还可以将字符串转换为双精度数。
如果我以后必须根据来自不同列的条件对整列或部分列执行算术操作,那么最好的方法是什么?例如,第1列有日期,我可能想要对第2列求和个月。
感谢。
答案 0 :(得分:2)
最直接的方法是使用DataTable
。例如:
DataTable tblCSV = new DataTable("CSV");
var fileInfo = new System.IO.FileInfo(fullPath);
var encoding = Encoding.GetEncoding(437); // use the correct encoding
using (var reader = new System.IO.StreamReader(fullPath, encoding))
{
//reader.ReadLine(); // skip all lines but header+data
Char quotingCharacter = '\0';//'"';
Char escapeCharacter = quotingCharacter;
using (var csv = new CsvReader(reader, true, Importer.FieldDelimiter, quotingCharacter, escapeCharacter, '\0', ValueTrimmingOptions.All))
{
csv.MissingFieldAction = MissingFieldAction.ParseError;
csv.DefaultParseErrorAction = ParseErrorAction.RaiseEvent;
csv.ParseError += csv_ParseError;
csv.SkipEmptyLines = true;
try
{
// load into DataTable
tblCSV.Load(csv, LoadOption.OverwriteChanges, csvTable_FillError);
然后你可以使用Linq-To-DataSet:
double avg = tblCSV.AsEnumerable()
.Select(r => int.Parse(r.Field<string>(13)))
.Average();