C# uses Linq and Loop to calculate the mean and variance of the collection [standard deviation]

variance [standard deviation]

The standard deviation formula is a mathematical formula . The standard deviation is also known as the standard deviation , or the experimental standard deviation, and the formula is as follows:

Sample standard deviation = arithmetic square root of variance = s=sqrt(((x1-x)^2 +(x2-x)^2 +......(xn-x)^2)/n)

Population standard deviation=σ=sqrt(((x1-x)^2 +(x2-x)^2 +......(xn-x)^2)/n )

Note: x in the above two standard deviation formulas is the arithmetic mean of a set of numbers (n data) . When all numbers (the number is n) appear probabilistically (the sum of the corresponding n probability values ​​is 1), then x is the mathematical expectation of this group of numbers .

formula meaning

All numbers (the number is n) are recorded as an array [n]. Sum all the numbers in the array and divide by n to get the arithmetic mean . All the numbers in the array are subtracted from the average value, and the obtained n differences are squared, and then all the square numbers obtained are summed, and then divided by the number of numbers or the number minus one. If the overall standard deviation is obtained , then Divide by n, if the sample standard deviation is obtained, divide by (n-1), and finally take the arithmetic square root of the obtained quotient , which is to take the 1/2 power, and the result obtained is the set of numbers (n data) standard deviation.

 Create a new form application, AverageAndDeviationDemo, and rename the default Form1 to FormAverageAndDeviation.

The source program of the view editor of the form FormAverageAndDeviation is as follows:

FormAverageAndDeviation.Designer.cs


namespace AverageAndDeviationDemo
{
    partial class FormAverageAndDeviation
    {
        /// <summary>
        /// 必需的设计器变量。
        /// </summary>
        private System.ComponentModel.IContainer components = null;

        /// <summary>
        /// 清理所有正在使用的资源。
        /// </summary>
        /// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Windows 窗体设计器生成的代码

        /// <summary>
        /// 设计器支持所需的方法 - 不要修改
        /// 使用代码编辑器修改此方法的内容。
        /// </summary>
        private void InitializeComponent()
        {
            this.rtxtMessage = new System.Windows.Forms.RichTextBox();
            this.btnGenerate = new System.Windows.Forms.Button();
            this.label1 = new System.Windows.Forms.Label();
            this.SuspendLayout();
            // 
            // rtxtMessage
            // 
            this.rtxtMessage.Location = new System.Drawing.Point(217, 95);
            this.rtxtMessage.Name = "rtxtMessage";
            this.rtxtMessage.Size = new System.Drawing.Size(687, 550);
            this.rtxtMessage.TabIndex = 0;
            this.rtxtMessage.Text = "";
            // 
            // btnGenerate
            // 
            this.btnGenerate.Location = new System.Drawing.Point(38, 93);
            this.btnGenerate.Name = "btnGenerate";
            this.btnGenerate.Size = new System.Drawing.Size(149, 23);
            this.btnGenerate.TabIndex = 1;
            this.btnGenerate.Text = "生成随机集合后开始比较";
            this.btnGenerate.UseVisualStyleBackColor = true;
            this.btnGenerate.Click += new System.EventHandler(this.btnGenerate_Click);
            // 
            // label1
            // 
            this.label1.AutoSize = true;
            this.label1.Location = new System.Drawing.Point(215, 64);
            this.label1.Name = "label1";
            this.label1.Size = new System.Drawing.Size(143, 12);
            this.label1.TabIndex = 2;
            this.label1.Text = "迭代Loop与Linq性能比较:";
            // 
            // FormAverageAndDeviation
            // 
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(981, 714);
            this.Controls.Add(this.label1);
            this.Controls.Add(this.btnGenerate);
            this.Controls.Add(this.rtxtMessage);
            this.Name = "FormAverageAndDeviation";
            this.Text = "计算集合平均值和标准差【方差】的示例";
            this.Load += new System.EventHandler(this.FormAverageAndDeviation_Load);
            this.ResumeLayout(false);
            this.PerformLayout();

        }

        #endregion

        private System.Windows.Forms.RichTextBox rtxtMessage;
        private System.Windows.Forms.Button btnGenerate;
        private System.Windows.Forms.Label label1;
    }
}

The form code is as follows:

FormAverageAndDeviation.cs

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace AverageAndDeviationDemo
{
    public partial class FormAverageAndDeviation : Form
    {
        public FormAverageAndDeviation()
        {
            InitializeComponent();
            rtxtMessage.ReadOnly = true;
        }

        /// <summary>
        /// 显示操作内容
        /// </summary>
        /// <param name="text"></param>
        private void DisplayMessage(string text) 
        {
            this.BeginInvoke(new Action(() => 
            {
                if (rtxtMessage.TextLength > 20480) 
                {
                    rtxtMessage.Clear();
                }
                rtxtMessage.AppendText($"{DateTime.Now.ToString("HH:mm:ss.fff")}->{text}\n");
                rtxtMessage.ScrollToCaret();
            }));
        }

        private void FormAverageAndDeviation_Load(object sender, EventArgs e)
        {
            List<double> array = new List<double>() { 1, 2, 3, 4, 5, 6 };
            CalculateAverageAndDeviation(array);
            CalculateAverageAndDeviationUseLoop(array);
        }

        /// <summary>
        /// 计算 平均值和 标准差【方差】
        /// 使用Linq迭代查询
        /// </summary>
        /// <param name="array"></param>
        private void CalculateAverageAndDeviation(IList<double> array) 
        {
            if (array == null || array.Count == 0) 
            {
                throw new ArgumentException($"无法对空集合求取平均值");
            }
            Stopwatch stopwatch = new Stopwatch();
            stopwatch.Start();
            //获取 平均值
            double average = array.Average();
            //获取方差之和
            double sumDeviation = array.Select(x => Math.Pow(x - average, 2)).Sum();
            //目标 标准差
            double standardDeviation = Math.Sqrt(sumDeviation / array.Count);
            stopwatch.Stop();
            double elapsedTime = stopwatch.Elapsed.TotalMilliseconds;//耗时ms
            DisplayMessage($"【Linq】average:{average}\nsumDeviation:{sumDeviation}\nstandardDeviation:{standardDeviation}\nElapsedTime:{elapsedTime}ms");
        }

        /// <summary>
        /// 计算 平均值和 标准差【方差】
        /// 使用循环迭代器
        /// </summary>
        /// <param name="array"></param>
        private void CalculateAverageAndDeviationUseLoop(IList<double> array)
        {
            if (array == null || array.Count == 0)
            {
                throw new ArgumentException($"无法对空集合求取平均值");
            }
            Stopwatch stopwatch = new Stopwatch();
            stopwatch.Start();
            double sum = 0;
            for (int i = 0; i < array.Count; i++)
            {
                sum += array[i];
            }
            //获取 平均值
            double average = sum / array.Count;
            sum = 0;
            for (int i = 0; i < array.Count; i++)
            {
                sum += Math.Pow(array[i] - average, 2);
            }
            //获取方差之和
            double sumDeviation = sum;
            //目标 标准差
            double standardDeviation = Math.Sqrt(sumDeviation / array.Count);
            stopwatch.Stop();
            double elapsedTime = stopwatch.Elapsed.TotalMilliseconds;//耗时ms
            DisplayMessage($"【Loop】average:{average}\nsumDeviation:{sumDeviation}\nstandardDeviation:{standardDeviation}\nElapsedTime:{elapsedTime}ms");
        }

        /// <summary>
        /// 生成10.0~99.9之间的随机集合
        /// </summary>
        /// <param name="count"></param>
        /// <returns></returns>
        private double[] GenerateRandomArray(int count) 
        {
            double[] array = new double[count];
            for (int i = 0; i < count; i++)
            {
                array[i] = new Random(i + 1).Next(100, 1000) * 0.1;
            }
            return array;
        }

        private async void btnGenerate_Click(object sender, EventArgs e)
        {
            double[] array = GenerateRandomArray(500);
            DisplayMessage($"打印源数组【{string.Join(",", array)}】");
            Task linqTask = Task.Run(() => CalculateAverageAndDeviation(array));
            Task loopTask = Task.Run(() => CalculateAverageAndDeviationUseLoop(array));
            Task.WaitAll(linqTask, loopTask);
            await loopTask;
        }
    }
}

The test runs as shown in the figure:

 

Guess you like

Origin blog.csdn.net/ylq1045/article/details/131805691