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
分隔任务。首先,创建一个函数,返回一列中的值:
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);