在不同项目开的发过程中,可能会用到许多相同或类似的功能开发或业务处理,从抽象设计的角度考虑,通常会把这些功能或业务操作进行封装,方便在不同项目中调用,这也是重用思想的重要体现。本次分享的是在C#中实现SPC过程能力相关方法的封转,是六西格玛数据统计工具类SixSigmaHelper类的功能补充。在大数据、人工智能、数据科学家炙手可热的当下,本类可以说是C#工程师在处理数据分析业务上的必备类。
相关概念请学习SPC相关课程和歇息MiniTab工具的使用
本类依赖SixSigmaHelper,请参看https://blog.csdn.net/zlbdmm/article/details/101770432
///
/// 直方图分组确定
///
/// 样本数
/// 返回分组数
public static int GetGroupNum(int length)
{
double k = 1 + 3.31 * Math.Log10(length);
return (int)Math.Floor(k);
}
///
/// 获取子组容量
///
/// 样本数
/// 子组数
/// 返回子组容量
public static int GetGroupSize(int length, int groupNum)
{
return (int)Math.Ceiling((decimal)length / (decimal)groupNum);
}
///
/// 获取望目值
///
/// 目标上限值
/// 目标下限值
/// 返回望目值
public static double GetTarget(double usl, double lsl)
{
return DoubleFormat(5, (usl + lsl) / 2);
}
///
/// 获取分辨率,如果返回resolution为0,则标识数组中数据均相同
///
/// 原始数据
/// 返回数据分辨率
public static double GetResolution(double[] original)
{
try
{
Array.Sort(original);
if (original.Length == 1)
{
return DoubleFormat(5, original[0]);
}
double resolution = 0.0;
for (int i = 1; i < original.Length; i++)
{
resolution = original[i] - original[i - 1];
if (resolution > 0)
{
break;
}
}
return DoubleFormat(5, resolution);
}
catch (Exception ex)
{
return 0.0;
}
}
///
/// 组距,数据有误或数据均相同时返回0
///
/// 精度,小数位数
/// 最大值
/// 最小值
/// 子组数
/// 原始数据
/// 返回组距
public static double GetGroupDistance(int digits, double max, double min, int groupNum, double[] original)
{
double gd = 0.0;
if (GetResolution(original) != 0)
{
double r = GetResolution(original);
double originalDistance = Math.Abs(max - min) / groupNum;
gd = DoubleFormat(digits, Math.Ceiling(originalDistance / r) * r);
}
return gd;
}
///
/// 获取组内左边界
///
/// 最小值
/// 组距
/// 子组数
/// 返回组内左边界
public static double[] GetGroupDownBound(double min, double groupDistance, int groupNum)
{
double[] gdb = new double[groupNum];
for(int i= 1;i <= groupNum; i++)
{
gdb[i - 1] = DoubleFormat(5, min + (i - 1) * groupDistance - groupDistance / 2);
}
return gdb;
}
///
/// 获取组内右边界
///
/// 最小值
/// 组距
/// 子组数
/// 返回组内右边界
public static double[] GetGroupUpBound(double min, double groupDistance, int groupNum)
{
double[] gub = new double[groupNum];
for(int i= 1;i <= groupNum; i++)
{
gub[i - 1] = DoubleFormat(5, min + (i - 1) * groupDistance + groupDistance / 2);
}
return gub;
}
///
/// 获取组内中值
///
/// 最小值
/// 组距
/// 子组数
/// 返回组内中值
public static double[] GetGroupMedian(double min, double groupDistance, int groupNum)
{
double[] gm = new double[groupNum];
for (int i = 1; i <= groupNum; i++)
{
gm[i - 1] = DoubleFormat(5, min + (i - 1) * groupDistance);
}
return gm;
}
///
/// 分布密度
///
/// 组距
/// 组内左边界
/// 组内右边界
/// 原始数据
/// 返回分布密度
public static double[] GetDistributionDensity(double groupDistance, double[] groupDownBound, double[] groupUpBound, double[] original)
{
double[] g = new double[groupUpBound.Length];
double[] count = new double[groupUpBound.Length];
//初始化count数值
for(int i= 0;i<count.Length;i++)
{
count[i] = 0.0;
}
for (int i = 0; i < groupUpBound.Length; i++)
{
for (int j = 0; j < original.Length; j++)
{
if (groupDownBound[i] < original[j] && original[j] < groupUpBound[i])
{
count[i] = count[i] + 1;
}
}
}
for (int i = 0; i < count.Length; i++)
{
g[i] = DoubleFormat(5, (count[i] / original.Length) * (1 / groupDistance));
}
return g;
}
///
/// 获取正态分布数据密度
///
/// 原始数据
/// 返回分布密度
public static double[] GetNormalDistribution(double[] original)
{
double[] values = new double[original.Length];
for (int i = 0; i < original.Length; i++)
{
values[i] = DoubleFormat(5, 1 / ((Math.Sqrt(2 * Math.PI) * SixSigmaHelper.GetTotalStdDev(original))) * Math.Pow(Math.E, -Math.Pow((original[i] - SixSigmaHelper.GetAverageValue(original)), 2) / (2 * Math.Pow(SixSigmaHelper.GetTotalStdDev(original), 2))));
}
return values;
}
///
/// 获取单个正态分布数据
///
///
/// 均值
/// 标准差
/// 返回单个正态分布数据
public static double GetNormalDistributionValue(double x, double ave, double stdDev)
{
return DoubleFormat(5, 1 / ((Math.Sqrt(2 * Math.PI) * stdDev)) * Math.Pow(Math.E, -Math.Pow((x - ave), 2) / (2 * Math.Pow(stdDev, 2))));
}
///
/// 获取组内正态分布数据密度
///
/// 子组数
/// 原始数据
/// 返回组内正态分布数据密度
public static double[] GetGroupNormalDistribution(int groupNum, double[] original)
{
double[] values = new double[original.Length];
double inGroupStdDev = SixSigmaHelper.GetInGroupStdDev(2, original);
double ave = SixSigmaHelper.GetAverageValue(original);
for (int i = 0; i < original.Length; i++)
{
values[i] = DoubleFormat(5, 1 / ((Math.Sqrt(2 * Math.PI) * inGroupStdDev) * Math.Pow(Math.E, -Math.Pow((original[i] - ave), 2) / (2 * Math.Pow(inGroupStdDev, 2)))));
}
return values;
}
///
/// 获取准确度
///
/// 目标上限
/// 目标下限
/// 均值
/// 返回准确度
public static double GetCA(double usl, double lsl, double ave)
{
double diff = (usl - lsl) / 2;
double sum = (usl + lsl) / 2;
return DoubleFormat(5, Math.Abs(sum - ave) / diff);
}
///
/// ppm小于lsl,ppm百万分之不良
///
/// 目标下限
/// 原始数据
/// 返回ppm小于lsl的值
public static double GetPpmLessLsl(double lsl, double[] original)
{
double count = 0.0;
for(int i= 0;i<original.Length;i++)
{
if (original[i] < lsl)
{
count += 1;
}
}
return DoubleFormat(5, (count / original.Length) * 1000000);
}
///
/// ppm大于usl,ppm百万分之不良
///
/// 目标上限
/// 原始数据
/// 返回ppm大于usl的值
public static double GetPpmMoreUsl(double usl, double[] original)
{
double count = 0.0;
for (int i = 0; i < original.Length; i++)
{
if (original[i] > usl)
{
count += 1;
}
}
return DoubleFormat(5, (count / original.Length) * 1000000);
}
///
/// 获取正三倍标准差
///
/// 目标值
/// 标准差
/// 返回目标值加上3倍的标准差
public static double GetPositive3Signa(double expTarget, double stdDev)
{
return DoubleFormat(5, expTarget + 3 * stdDev);
}
///
/// 获取负三倍标准差
///
/// 目标值
/// 标准差
/// 返回目标值减去3倍的标准差
public static double GetNegative3Signa(double expTarget, double stdDev)
{
return DoubleFormat(5, expTarget - 3 * stdDev);
}
完整代码下载