我有一个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"])....
答案 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)