• GitHub上的最新资源
  • 现在带有NuGet软件包

介绍

在进行另一个项目时,我发现自己需要计算各种基础类型的各种数据集的基本统计信息。LINQ有Count,Min,Max和Average,但没有其他统计汇总。像我在这种情况下经常做的那样,我从Google开始,认为其他人一定已经为此写了一些方便的扩展方法。有大量的统计和数值处理程序包,但是我想要的是一种简单且轻便的基本统计数据实现:方差(样本和总体),标准差(样本和总体),协方差,皮尔逊(卡方),范围,中位数,最小二乘,均方根,直方图和众数。

背景

我已经针对Enumerable.Average的各种重载对API进行了建模,因此您可以在这些方法接受的相同类型的集合上使用这些方法。希望这将使用法熟悉和易于使用。

这意味着常见数字数据类型及其Nullable计数器部分的集合会产生重载,而便捷的选择器也将产生重载。

public static decimal? StandardDeviation(this IEnumerable<decimal?> source);
public static decimal StandardDeviation(this IEnumerable<decimal> source);
public static double? StandardDeviation(this IEnumerable<double?> source);
public static double StandardDeviation(this IEnumerable<double> source);
public static float? StandardDeviation(this IEnumerable<float?> source);
public static float StandardDeviation(this IEnumerable<float> source);
public static double? StandardDeviation(this IEnumerable<int?> source);
public static double StandardDeviation(this IEnumerable<int> source);
public static double? StandardDeviation(this IEnumerable<long?> source);
public static double StandardDeviation(this IEnumerable<long> source);
public static decimal? StandardDeviation<TSource>(this IEnumerable<TSource> source, Func<TSource, decimal?> selector);
public static decimal StandardDeviation<TSource>(this IEnumerable<TSource> source, Func<TSource, decimal> selector);
public static double? StandardDeviation<TSource>(this IEnumerable<TSource> source, Func<TSource, double?> selector);
public static double StandardDeviation<TSource>(this IEnumerable<TSource> source, Func<TSource, double> selector);
public static float? StandardDeviation<TSource>(this IEnumerable<TSource> source, Func<TSource, float?> selector);
public static float StandardDeviation<TSource>(this IEnumerable<TSource> source, Func<TSource, float> selector);
public static double? StandardDeviation<TSource>(this IEnumerable<TSource> source, Func<TSource, int?> selector);
public static double StandardDeviation<TSource>(this IEnumerable<TSource> source, Func<TSource, int> selector);
public static double? StandardDeviation<TSource>(this IEnumerable<TSource> source, Func<TSource, long?> selector);
public static double StandardDeviation<TSource>(this IEnumerable<TSource> source, Func<TSource, long> selector);

所有采用Nullable类型集合的重载仅在计算结果中包括实际值。例如:

public static double? StandardDeviation(this IEnumerable<double?> source)
{IEnumerable<double> values = source.AllValues();if (values.Any())return values.StandardDeviation();return null;
}

其AllValues方法是:

public static IEnumerable<T> AllValues<T>(this IEnumerable<T?> source) where T : struct
{Debug.Assert(source != null);return source.Where(x => x.HasValue).Select(x => (T)x);
}

关于模式的注意事项

由于值的分布可能没有模式,因此所有Mode方法都返回Nullable类型。例如,在连续的{ 1, 2, 3, 4 }中,没有一个值出现多次。在这种情况下,返回值为null。

在存在多种模式的情况下,Mode返回最大模式(即,出现次数最多的值)。如果最大模式并列,它将返回最大模式集合中的最小值。

还有两种方法可以计算一系列的所有模式。它们以模态降序返回所有模式IEnumerable中的一个。

统计计算

Wikipedia的链接,描述和数学图像。

方差

方差是对一个变量的所有分数的变化量的度量(不仅仅是给出范围的极端值)。

样本方差通常由小写的西格玛平方表示:σ 2

public static double Variance(this IEnumerable<double> source)
{ int n = 0;double mean = 0;double M2 = 0;foreach (double x in source){n = n + 1;double delta = x - mean;mean = mean + delta / n;M2 += delta * (x - mean);}return M2 / (n - 1);
}

标准偏差

统计总体,数据集或概率分布的标准偏差是其方差的平方根。

标准偏差通常由小写的σ表示

public static double StandardDeviation(this IEnumerable<double> source)
{ return Math.Sqrt(source.Variance());
}

中位数

中位数是将样本的上半部分,总体或概率分布与下半部分分开的数字。

public static double Median(this IEnumerable<double> source)
{ var sortedList = from number in source orderby number select number; int count = sortedList.Count(); int itemIndex = count / 2; if (count % 2 == 0) // Even number of items. return (sortedList.ElementAt(itemIndex) + sortedList.ElementAt(itemIndex - 1)) / 2; // Odd number of items. return sortedList.ElementAt(itemIndex);
}

模式

模式是在数据集或概率分布中最频繁出现的值。

public static T? Mode<T>(this IEnumerable<T> source) where T : struct
{var sortedList = from number in sourceorderby numberselect number;int count = 0;int max = 0;T current = default(T);T? mode = new T?();foreach (T next in sortedList){if (current.Equals(next) == false){current = next;count = 1;}else{count++;}if (count > max){max = count;mode = current;}}if (max > 1)return mode;return null;
}

直方图

直方图是数据的连续分布的表示。在给定连续数据集的情况下,直方图会统计其数据点出现在一组连续值范围(即bin)中的次数。没有单一的方法来确定bin的数量,因为这取决于所执行的数据和分析。有一些标准机制可用于根据数据点的数量来计算bin大小。其中的三个包含在一组BinCount扩展方法中。也有不同的方法来确定每个容器的范围。这些用BinningMode举表示。在所有情况下,除一个以外,bin范围都包含>=最小值范围和<最大值范围;[min, max)。当BinningMode是MaxValueInclusive,则最大bin范围将包括最大值而不是将其排除:[min, max]。

/// <summary>
/// Controls how the range of the bins are determined
/// </summary>
public enum BinningMode
{/// <summary>/// The minimum will be equal to the sequence min and the maximum equal to infinity/// such that:/// [min, min + binSize), [min * i, min * i + binSize), ... , [min * n, positiveInfinity)/// </summary>Unbounded,/// <summary>/// The minimum will be the sequence min and the maximum equal to sequence max/// The last bin will max inclusive instead of exclusive/// </summary>/// [min, min + binSize), [min * i, min * i + binSize), ... , [min * n, max]MaxValueInclusive,/// <summary>/// The total range will be expanded such that the min is/// less then the sequence min and max is greater then the sequence max/// [min - (binSize / 2), min - (binSize / 2) + binSize), /// [min - (binSize / 2) * i, min - (binSize / 2) * i + binSize), ... , /// [min - (bin / 2) * n, min + (binSize / 2))/// </summary>ExpandRange
}

创建直方图包括创建具有适当范围的Bin数组,然后确定每个范围内有多少个数据点。

public static IEnumerable<Bin> Histogram
(this IEnumerable<double> source, int binCount, BinningMode mode = BinningMode.Unbounded)
{if (source == null)throw new ArgumentNullException("source");if (!source.Any())throw new InvalidOperationException("source sequence contains no elements");var bins = BinFactory.CreateBins(source.Min(), source.Max(), binCount, mode);source.AssignBins(bins);return bins;
}

范围

范围是包含所有数据的最小间隔的长度。

public static double Range(this IEnumerable<double> source)
{return source.Max() - source.Min();
}

协方差

协方差是两个变量一起变化多少的度量。

public static double Covariance(this IEnumerable<double> source, IEnumerable<double> other)
{int len = source.Count();double avgSource = source.Average();double avgOther = other.Average();double covariance = 0;for (int i = 0; i < len; i++)covariance += (source.ElementAt(i) - avgSource) * (other.ElementAt(i) - avgOther);return covariance / len;
}

皮尔逊卡方检验

皮尔逊卡方检验用于评估两种比较类型:拟合优度检验和独立性检验。

换句话说,它是样本分布与预测分布的匹配程度或两个样本分布之间的相关程度的度量。皮尔逊定律经常在科学应用中用于检验假设的有效性。

public static double Pearson(this IEnumerable<double> source, IEnumerable<double> other)
{return source.Covariance(other) / (source.StandardDeviationP() * other.StandardDeviationP());
}

线性最小二乘法

最小二乘法是一种确定回归分析中使用的数据分布的近似解的方法。换句话说,给定二维数据的分布,最能预测y的形式为x的方程式为y = mx + b,其中m是直线的斜率,并且b是它在二维图像上与y轴的交点。

对于此计算,返回一个表示m和 b的struct。

public static LeastSquares LeastSquares(this IEnumerable<Tuple<double, double>> source)
{int numPoints = 0;double sumX = 0;double sumY = 0;double sumXX = 0;double sumXY = 0;foreach (var tuple in source){numPoints++;sumX += tuple.Item1;sumY += tuple.Item2;sumXX += tuple.Item1 * tuple.Item1;sumXY += tuple.Item1 * tuple.Item2;}if (numPoints < 2)throw new InvalidOperationException("Source must have at least 2 elements");double b = (-sumX * sumXY + sumXX * sumY) / (numPoints * sumXX - sumX * sumX);double m = (-sumX * sumY + numPoints * sumXY) / (numPoints * sumXX - sumX * sumX);return new LeastSquares(m, b);
}

均方根

均方根是变化序列的大小的度量。这对于波形特别有用。

public static double RootMeanSquare(this IEnumerable<double> source)
{if (source.Count() < 2)throw new InvalidOperationException("Source must have at least 2 elements");double s = source.Aggregate(0.0, (x, d) => x += Math.Pow(d, 2));return Math.Sqrt(s / source.Count());
}

使用代码

包含的单元测试应提供许多有关如何使用这些方法的示例,但最简单的是,它们的行为类似于其他可枚举的扩展方法。以下程序...

static void Main(string[] args)
{IEnumerable<int> data = new int[] { 1, 2, 5, 6, 6, 8, 9, 9, 9 };Console.WriteLine("Count = {0}", data.Count());Console.WriteLine("Average = {0}", data.Average());Console.WriteLine("Median = {0}", data.Median());Console.WriteLine("Mode = {0}", data.Mode());Console.WriteLine("Sample Variance = {0}", data.Variance());Console.WriteLine("Sample Standard Deviation = {0}", data.StandardDeviation());Console.WriteLine("Population Variance = {0}", data.VarianceP());Console.WriteLine("Population Standard Deviation = {0}", data.StandardDeviationP());Console.WriteLine("Range = {0}", data.Range());
}

...产生:

Count = 9
Average = 6.11111111111111
Median = 6
Mode = 9
Sample Variance = 9.11111111111111
Sample Standard Deviation = 3.01846171271247
Population Variance = 8.09876543209877
Population Standard Deviation = 2.8458329944146
Range = 8

兴趣点

我没有花很多时间优化计算,因此如果您要评估非常大的数据集,请务必小心。

希望下次需要进行一些简单的统计计算时,可以找到此代码。

关于T4模板的注释

我从来没有发现代码生成模板有多少用处,但是在开发此库时,它们极大地简化了一个用例:即算术运算不能直接在C#泛型中表示。因为运算符被实现为static方法,并且没有机制要求Type具有特定的static方法,所以编译器无法在此代码段中通用地解析“-”:

public static T Range<T>(this IEnumerable<T> source)
{// error CS0019: Operator '-' cannot be applied to operands of type 'T' and 'T'return source.Max() - source.Min();
}

如果您查看框架类中由Average和Sum设置的模式(我在这里试图模拟),他们对int,long,float,double和decimal进行枚举操作。为了避免过多的“复制、粘贴、修改代码和注释中的操作数类型”,T4模板非常方便。

基本上,对于可以对一组固有类型进行操作的每个操作,模板:

  1. 声明支持的类型的列表
  2. 遍历列表并为支持给定固有类型的所有重载生成代码注释、方法签名和主体
 
  public static partial class EnumerableStats{<# var types = new List<string>(){"int", "long", "float", "double", "decimal"};foreach(var type in types){#> /// <summary>/// Computes the Range of a sequence of nullable <#= type #> values./// </summary>/// <param name="source">The sequence of elements.</param>/// <returns>The Range.</returns>public static <#= type #>? Range(this IEnumerable<<#= type #>?> source){IEnumerable<<#= type #>> values = source.AllValues();if (values.Any())return values.Range();return null;}/// <summary>/// Computes the Range of a sequence of <#= type #> values./// </summary>/// <param name="source">The sequence of elements.</param>/// <returns>The Range.</returns>public static <#= type #> Range(this IEnumerable<<#= type #>> source){return source.Max() - source.Min();}...etc etc...
<# } #>}

这样很好,因为它可以确保所有类型都支持相同的重载集合,并具有相同的实现和代码注释。

使用LINQ计算基本统计相关推荐

  1. 获取以逗号分隔的多个数据输入成列表,计算基本统计值(平均值、标准差、中位数)‪‬‪‬‪‬‪‬‪‬‮‬‪‬‭‬‪‬‪‬‪‬‪‬‪‬‮‬‭‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‫‬‪‬‪‬‪‬‪‬‪‬

    获取以逗号分隔的多个数据输入(输入为一行),计算基本统计值(平均值.标准差.中位数)‪‬‪‬‪‬‪‬‪‬‮‬‪‬‭‬‪‬‪‬‪‬‪‬‪‬‮‬‭‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‫‬‪‬‪‬‪‬‪‬‪‬ ...

  2. Python 数据分析三剑客之 Pandas(五):统计计算与统计描述

    CSDN 课程推荐:<迈向数据科学家:带你玩转Python数据分析>,讲师齐伟,苏州研途教育科技有限公司CTO,苏州大学应用统计专业硕士生指导委员会委员:已出版<跟老齐学Python ...

  3. jQuery实现购物车计算价格统计功能

    jQuery实现购物车计算价格统计功能 #功能介绍 进入界面,刷新触发onload方法跳转到JS代码,可以对购物车内商品数量进行增加-减少,商品价格自动统计.当更改商品数量的输入框value值时,整个 ...

  4. NCBI中对所有原核生物ANI计算的统计结果简单讲解

    NCBI中对所有原核生物ANI计算的统计结果简单讲解 来龙去脉还没搞清楚,就先从结果切入.放上一个计算结果的链接https://ftp.ncbi.nlm.nih.gov/genomes/ASSEMBL ...

  5. 常用的数量统计量的计算及统计意义

    数量统计量是只适合数量类型数据的统计量,使我们最常见的统计量.笔者之前对资料特征数的计算作了简单地介绍,详情可跳转至 资料特征数的计算,本篇博客力求全面和简洁易懂. 对于数量类型的数据样本 X1,X2 ...

  6. redis数量计算(统计访问量等等)

    目录 HyperLogLog hash BitSet 传送带 HyperLogLog 1.HyperLogLog算法,存在误差(只记录key,不记录实际的值) 链接 hash 通过hset 域 key ...

  7. r 语言计算欧氏距离_一文搞懂常用R语言统计值计算:打倒描述性统计拦路虎

    本文来自:R语言:用R计算各种统计值 作者:生物信息学习 目录: 求极差(range) 做频数分布表和频数分布图(graph of frequency distribution) 算术平均数(mean ...

  8. 如何用python完成基本统计信息计算_如何用python计算基本统计值?

    如何用python计算基本统计值? 用python计算基本统计值的代码为def getNum(): #从控制台获取多个不确定数据的方法 nums = []; iNumStr = input(" ...

  9. 如何用计算机计算概率,A-level数学考试计算器使用攻略:手把手教你用FX991计算器计算分布概率和统计数据...

    前言 之前有小伙伴想了解A Level数学考试中该如何使用计算器的问题,并希望得到一些计算器使用的建议.那么今天,我们就和大家聊聊关于A Level计算器的使用,希望能够帮助到大家- A Level考 ...

最新文章

  1. Matlab符号运算 - 解微分方程
  2. java闭锁_java8中CountDownLatch闭锁
  3. python3 正则表达式点星问号(.*?)能不能匹配换行符?不能的话应该怎么写
  4. [J2ME QA]真机报告MontyThread -n的错误之解释
  5. 系统架构师 项目经理 哪个更有前景_中央空调加地暖与五恒系统,哪个更省钱?...
  6. 【壹刊】Azure AD(三)Azure资源的托管标识
  7. python网站服务器好麻烦_python写的网站,云服务器经常无法访问
  8. java heap 查看_使用VisualVM查看Java Heap Dump
  9. Practice - iOS 项目持续集成实践(一)
  10. VC++ MsChart控件怎么用?
  11. 《设计模式沉思录》分享
  12. 存储运维知识点记录(netapp,华为,HP-3par,emc)
  13. Linux常用基础指令
  14. 华为od一面面试算法
  15. Camera2 openCamera 流程分析
  16. C++字符函数库 cctype
  17. Spring4 学习教程
  18. 人工智能或重塑区域经济发展格局
  19. erp5开源制造业erp短信发送接收机制
  20. 更好的Helvetica

热门文章

  1. 手机mt4一键平仓所有_手机一键就能提取PPT所有文字!10秒完成,这波操作好用到你害怕...
  2. java 情况浏览器缓存_JavaWeb禁止浏览器缓存当前Web页面的方法
  3. ajax后台返回数据中文乱码_ajax返回的数据是乱码????
  4. 请写出至少五个块级元素_Java 面试题(五)
  5. mysql gps海拔表_GPS海拔表
  6. java panel 所有事件_java-侦听/处理JPanel事件
  7. python编译环境对cpu要求高不高_解决Tensorflow 使用时cpu编译不支持警告的问题
  8. 喜庆红色C4D立体电商首焦模板|PSD分层格式,设计师大呼真香!
  9. 平面设计素材模板| 还在为封面设计烦恼么?
  10. 大火金九银十!秋季借势海报PSD分层模板,看谁最能俘获你的心