0

我正在平均 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 开始,因为我只想对第五列之后的每一列进行平均。被平均的列中的数据是双精度类型。如果我删除我试图删除 0 值的代码,则代码运行,但如果例如我平均第一列并且该列有 10 行但其中 3 行包含 0,它将把所有行加在一起并除以 10我需要它除以 7

4

2 回答 2

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];
    }
}

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

var avg =  GetColumnValues(DT2, colIndex).OfType<double>()
           .Where(d => d > 0).Average();
于 2013-04-02T15:19:13.363 回答
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);
于 2013-04-02T13:48:39.767 回答