c#中2D数组的方差和平均值



我正在阅读这篇文章,我试图遵循他们的代码示例,但我认为我错过了一个库。

他们有这个:

首先,让我们用一些随机数据创建一个2D矩阵。我们将使用系统。生成伪随机数的随机类:

var rand = new Random();
var matrix = new double[5, 5];
for (int i = 0; i < matrix.GetLength(0); i++)
{
for (int j = 0; j < matrix.GetLength(1); j++)
{
matrix = rand.NextDouble() * 100;
}
}

现在我们有了数据,我们可以计算平均值标准差:

double mean = matrix.Average();
double stdDev = Math.Sqrt(matrix.Variance());

但是当我在c#中尝试时,我得到这个编译时错误:

项目文件行抑制状态错误CS1061 'double[]'不包含'Variance'的定义可访问的扩展方法'Variance'接受类型为'double[]'的第一个参数'可以找到(您是否缺少using指令或程序集引用?)

添加我试着

using System.Numerics;

但没有帮助

如果您想将Linq方法应用于2D数组T[,]项,您可以使用OfType()(或Cast<T>())来获得枚举IEnumeration<T>。例如,在Average()的情况下,您可以将其设置为

using System.Linq;
...
var matrix = new double[5,5];
...
double mean = matrix
.OfType<double>() 
.Average();

由于标准Linq没有(至少在。net 6中)Variance方法,我们应该做一个简单的统计。有x = {x_1, x_2, x_3, ..., x_N}N项目的序列,方差将是

Var(x) = Sum(x * x) / N - Sum(x) * Sum(x) / N / N

在我们的例子中,可以是一个简单的Aggregate:

// Let's compute all required statistics 
//   n  - number of items
//   s  - sum of items
//   s  - sum of items squared
// in one go with a help of Aggregate 
var stat = matrix
.OfType<double>()
.Aggregate((n: 0, s: 0.0, ss: 0.0), (s, a) => (s.n + 1, s.s + a, s.ss + a * a));
double stdDev = Math.Sqrt(stat.ss / stat.n - stat.s * stat.s / stat.n / stat.n); 

为了不处理这样的结构,可以实现扩展方法:

public static partial class Array2dExtensions {
public static double Average(this double[,] matrix) {
if (matrix == null)
throw new ArgumentNullException(nameof(matrix));
return matrix
.OfType<double>() 
.Average();
}
public static double Variance(this double[,] matrix) {
if (matrix == null)
throw new ArgumentNullException(nameof(matrix));
var stat = matrix
.OfType<double>()
.Aggregate((n: 0, s: 0.0, ss: 0.0), (s, a) => 
(s.n + 1, s.s + a, s.ss + a * a));
return stat.ss / stat.n - stat.s * stat.s / stat.n / stat.n; 
}
}

有了这个实现,你可以把它放在如果数组有AverageVariance方法:

double mean = matrix.Average();
double stdDev = Math.Sqrt(matrix.Variance());

最新更新