从多个数字数组创建平均数组的最快方法

Pet*_*ter 9 c# arrays

我有多个Float相同大小和单个维度的输入数组.我想创建一个包含所有输入数组平均值的输出数组.

例如

//input arrays
float[] array1 = new float[] { 1, 1, 1, 1 };
float[] array2 = new float[] { 2, 2, 2, 2 };
float[] array3 = new float[] { 3, 3, 3, 3 };
float[] array4 = new float[] { 4, 4, 4, 4 };

//the output should be
float[2.5, 2.5, 2.5, 2.5]
Run Code Online (Sandbox Code Playgroud)

我还想计算输入数组的标准偏差.

执行此任务的最快方法是什么?

提前致谢.皮特

Jon*_*Jon 9

LINQ来救援

本文详细介绍了如何使用LINQ实现目标,以最大的可重用性和多功能性为主要目标.

取1(为方便起见,将LINQ打包成方法)

采取这种方法:

float[] ArrayAverage(params float[][] arrays)
{
    // If you want to check that all arrays are the same size, something
    // like this is convenient:
    // var arrayLength = arrays.Select(a => a.Length).Distinct().Single();

    return Enumerable.Range(0, arrays[0].Length)
               .Select(i => arrays.Select(a => a.Skip(i).First()).Average())
               .ToArray();
}
Run Code Online (Sandbox Code Playgroud)

它的工作原理是取范围,[0..arrays.Length-1]i计算范围内的每个数字,计算i每个数组的第th个元素的平均值.它可以非常方便地使用:

float[] array1 = new float[] { 1, 1, 1, 1 };
float[] array2 = new float[] { 2, 2, 2, 2 };
float[] array3 = new float[] { 3, 3, 3, 3 };
float[] array4 = new float[] { 4, 4, 4, 4 };

var averages = ArrayAverage(array1, array2, array3, array4);
Run Code Online (Sandbox Code Playgroud)

这可以在任何数量的阵列上使用而无需修改.但你可以再迈出一步,做一些更普遍的事情.

取2(对任何聚合函数进行推广)

float[] ArrayAggregate(Func<IEnumerable<float>, float> aggregate, params float[][] arrays)
{
    return Enumerable.Range(0, arrays[0].Length)
               .Select(i => aggregate(arrays.Select(a => a.Skip(i).First())))
               .ToArray();
}
Run Code Online (Sandbox Code Playgroud)

这可用于计算任何聚合函数:

var output = ArrayAggregate(Enumerable.Average, array1, array2, array3, array4);
Run Code Online (Sandbox Code Playgroud)

而不是Enumerable.Average你可以替换任何方法,扩展方法或匿名函数 - 这是有用的,因为没有内置的标准偏差聚合函数,并且这种方式的ArrayAggregate功能是非常通用的.但我们仍然可以做得更好.

取3(对任何聚合函数和任何类型的数组进行推广)

我们还可以制作适用于任何内置类型的通用版本:

T[] ArrayAggregate<T>(Func<IEnumerable<T>, T> aggregate, params T[][] arrays)
{
    return Enumerable.Range(0, arrays[0].Length)
               .Select(i => aggregate(arrays.Select(a => a.Skip(i).First())))
               .ToArray();
}
Run Code Online (Sandbox Code Playgroud)

您可能已经知道,这不是执行此工作的最快代码.如果您的计划花费全天计算平均值,请使用更接近金属的东西.但是,如果你想要可重用性和多功能性,我认为你不能比上面做得更好.


Yur*_*ich 4

就性能而言,最快的方法是,除非您想展开 for 循环

float[] sums = new float[4];

for(int i = 0; i < 4; i++)
{
    sums[i] = (array1[i]+ array2[i] + array3[i] + array4[i])/4;
}
Run Code Online (Sandbox Code Playgroud)