Linq Lambda平均DataTable列 - 删除0个值

时间:2013-04-02 13:12:20

标签: c# linq lambda datatable average

我在DataTable中平均每一列,并将这些平均值添加到列表中。如何防止平均值包含0?我已尝试过以下代码,但收到错误,即操作符!=无法应用于object[]int类型的操作数

for (int col = 5; col < DT2.Columns.Count; col++)
{
    double avg = DT2.AsEnumerable()
                 .Where(x => 
                     x[DT2.Columns[col]] != DBNull.Value || 
                     x[DT2.Rows[col].ItemArray != 0)
                 .Average(x => double.Parse(x[DT2.Columns[col]].ToString()));
    averages.Add(avg);
}

我从col = 5开始,因为我只想在第五列之后平均每一列。平均列中的数据是double类型。如果我删除我试图删除0值的代码,代码会运行,但是如果我平均第一列而列有10行但其中3行包含0,它会将所有行加在一起并除以10在哪里我需要它除以7

2 个答案:

答案 0 :(得分:0)

如果您只想要5之后的列,则可以使用内联列。

var columns = DT2.Columns.Cast<DataColumn>().Skip(5);
var rows = DT2.AsEnumerable();

IEnumerable<double> rowAverages =
      rows
        .Select(r =>
            columns
                .Where(c =>
                    r[c] != DBNull.Value &&
                    r[c] is double &&
                    ((double)r[c]) > 0)
                .Select(c =>
                    (double)r[c]))
        .Select(r =>
            r.Any() ? r.Average() : 0);

IEnumerable<double> columnAverages =
      columns
        .Select(c =>
            rows.Where(r =>
                    r[c] != DBNull.Value &&
                    r[c] is double &&
                    ((double)r[c]) > 0)
                .Select(r => (double)r[c]))
        .Select(c => c.Any() ? c.Average() : 0);

答案 1 :(得分:0)

分开任务。首先,创建一个在一列中返回值的函数:

IEnumerable<object> GetColumnValues(DataTable dt, int columnIndex)
{
    if (dt.Columns.Count < columnIndex + 1)
        yield break;
    foreach (DataRow row in dt.Rows)
    {
        if (row[columnIndex] != DBNull.Value)
            yield return row[columnIndex];
    }
}

现在您已经有了获取列值的方法,接下来您可以决定如何处理它们。例如,迭代您的列和每列do:

var avg =  GetColumnValues(DT2, colIndex).OfType<double>()
           .Where(d => d > 0).Average();