将数据表转换为双精度数组

时间:2017-04-13 13:34:03

标签: c# arrays

我有一个DataTable对象作为SQL读取的结果。典型示例包含100行和16列。我需要多次迭代表,提取计算值(应用程序是机器学习梯度下降)。 我正在尝试加快计算速度,并避免每次使用时都必须转换从DataTable读取的值。有没有办法通过将整个DataTable对象强制转换一次来创建新的2D索引数组,因此无需调用Convert.ToDouble 1000x100x16 = 1,600,000次。理想情况下,为了代码可读性,我希望保留引用数据为[“colname”,row]

目前的实施:

for(i=0;i<1000;i++)
  foreach (DataRow row in dt.Rows)
    calculation = Convert.ToDouble(row["col1"])....

4 个答案:

答案 0 :(得分:3)

使用:

using System;
using System.Linq;
using System.Data;    
DataTable db = <some table>;
double[][] arrayOfDoubles = db.AsEnumerable().Select(x => new [] { Convert.ToDouble(x["SomeColumn"]), Convert.ToDouble(x["SomeColumn"]), ... }).ToArray();

别忘了检查DbNull

答案 1 :(得分:2)

您需要一个自定义对象来保存每行的单元格值:

public class Dto // you can chose better name for dto class
{
   public double Column1 { get; set; }
   // other properties go here
}

接下来将数据表转换为此类对象的字典,并将行索引作为键:

var map = dt.AsEnumerable()
            .Select((r,i) => new { 
                RowIndex = i,
                Value = new Dto { 
                    Column1 = r.Field<double>("col1") 
                    // parse other columns here
                }                    
             }))
            .ToDictionary(x => x.RowIndex, x => x.Value);

之后,您将能够将列值引用为

map[rowIndex].Column1

答案 2 :(得分:0)

dt.Rows.Select(r => Convert.ToDouble(r["col1"])).ToArray()将返回  数组double,与原始DataTable的顺序相同。您不需要存储对源行的引用,因为您正在检查istelf的索引将是原始行的索引。

请注意,您需要导入System.Linq并添加System.Data.DatasetExtensions的引用才能使用此方法。

在循环外执行此操作,然后在生成的数组上运行循环:

var arr = dt.Rows.Select(r => Convert.ToDouble(r["col1"])).ToArray();

for(i=0;i<1000;i++)
    for(j=0;j<arr.Length;j++)
    {
        calculation = arr[j] /* your operation here */;
        //dt.Rows[j] is also available if needed at any time
    }   

答案 3 :(得分:0)

您可以创建一个类来保存您的数字,甚至可以进行一些计算。

csh_model_right = lme(y ~ trt*visit*grp,                          # fixed effects 
                  random      = ~1|subject,                   # random effects 
                  data        = subject_table,                # data
                  weights     = varIdent(form=~1|visit),      # different "weight" within each visit (I know)
                  correlation = corCompSymm(),                # CS correlation matrix within subject per random statement above
                  control     = lme.control)