0

我有一个大的 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()

显然不起作用,尤其是因为它的所有字符串。

将结构化的数据导入到一个类中会更好,或者将大二维列表的整个列转换为一维列表,如果它们是数字,我还可以将字符串转换为双精度值。

如果我必须稍后根据来自不同列的标准对整个列或列的一部分执行算术运算,最好的方法是什么,例如第 1 列有日期,我可能想按月对第 2 列求和。

谢谢。

4

1 回答 1

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();
于 2013-07-08T15:50:29.837 回答