Linq Lambda平均数据表列-删除0值

本文关键字:删除 数据表 Lambda Linq | 更新日期: 2023-09-27 18:07:14

我对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

Linq Lambda平均数据表列-删除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();

如果您只需要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);