public Statistics(IEnumerable <double> values) { OriginalValues = values.Where(d => !double.IsNaN(d)).ToArray(); SortedValues = OriginalValues.OrderBy(value => value).ToArray(); N = SortedValues.Count; if (N == 0) { throw new InvalidOperationException("Sequence of values contains no elements, Statistics can't be calculated"); } if (N == 1) { Q1 = Median = Q3 = SortedValues[0]; } else { double GetMedian(IReadOnlyList <double> x) => x.Count % 2 == 0 ? (x[x.Count / 2 - 1] + x[x.Count / 2]) / 2 : x[x.Count / 2]; Median = GetMedian(SortedValues); Q1 = GetMedian(SortedValues.Take(N / 2).ToList()); Q3 = GetMedian(SortedValues.Skip((N + 1) / 2).ToList()); } Min = SortedValues.First(); Mean = SortedValues.Average(); Max = SortedValues.Last(); InterquartileRange = Q3 - Q1; LowerFence = Q1 - 1.5 * InterquartileRange; UpperFence = Q3 + 1.5 * InterquartileRange; AllOutliers = SortedValues.Where(IsOutlier).ToArray(); LowerOutliers = SortedValues.Where(IsLowerOutlier).ToArray(); UpperOutliers = SortedValues.Where(IsUpperOutlier).ToArray(); Variance = N == 1 ? 0 : SortedValues.Sum(d => Math.Pow(d - Mean, 2)) / (N - 1); StandardDeviation = Math.Sqrt(Variance); StandardError = StandardDeviation / Math.Sqrt(N); Skewness = CalcCentralMoment(3) / StandardDeviation.Pow(3); Kurtosis = CalcCentralMoment(4) / StandardDeviation.Pow(4); ConfidenceInterval = new ConfidenceInterval(Mean, StandardError, N); Percentiles = new PercentileValues(SortedValues); }
/// <summary> /// Determine if either x or y values are sorted; if neither, sort x. /// </summary> private void DetermineSorted() { SortedToUnsorted = Enumerable.Range(0, xTransformed.Length).ToArray(); if (IsSorted(xTransformed)) { TransformedSorted = xTransformed; SortedValues = SortedValues.X; } else if (IsSorted(yTransformed)) { TransformedSorted = yTransformed; SortedValues = SortedValues.Y; } else { TransformedSorted = (double[])xTransformed.Clone(); Array.Sort(TransformedSorted, SortedToUnsorted); } }
public Statistics(IEnumerable <double> values) { OriginalValues = values.Where(d => !double.IsNaN(d)).ToArray(); SortedValues = OriginalValues.OrderBy(value => value).ToArray(); N = SortedValues.Count; if (N == 0) { throw new InvalidOperationException("Sequence of values contains no elements, Statistics can't be calculated"); } var quartiles = Quartiles.FromSorted(SortedValues); Min = quartiles.Min; Q1 = quartiles.Q1; Median = quartiles.Median; Q3 = quartiles.Q3; Max = quartiles.Max; InterquartileRange = quartiles.InterquartileRange; var moments = Moments.Create(SortedValues); Mean = moments.Mean; StandardDeviation = moments.StandardDeviation; Variance = moments.Variance; Skewness = moments.Skewness; Kurtosis = moments.Kurtosis; var tukey = TukeyOutlierDetector.FromQuartiles(quartiles); LowerFence = tukey.LowerFence; UpperFence = tukey.UpperFence; AllOutliers = SortedValues.Where(tukey.IsOutlier).ToArray(); LowerOutliers = SortedValues.Where(tukey.IsLowerOutlier).ToArray(); UpperOutliers = SortedValues.Where(tukey.IsUpperOutlier).ToArray(); outlierDetector = tukey; StandardError = StandardDeviation / Math.Sqrt(N); ConfidenceInterval = new ConfidenceInterval(Mean, StandardError, N); Percentiles = new PercentileValues(SortedValues); }
public Statistics(IEnumerable <double> values) { OriginalValues = values.Where(d => !double.IsNaN(d)).ToArray(); SortedValues = OriginalValues.OrderBy(value => value).ToArray(); N = SortedValues.Count; if (N == 0) { throw new InvalidOperationException("Sequence of values contains no elements, Statistics can't be calculated"); } if (N == 1) { Q1 = Median = Q3 = SortedValues[0]; } else { double GetMedian(IReadOnlyList <double> x) => x.Count % 2 == 0 ? (x[x.Count / 2 - 1] + x[x.Count / 2]) / 2 : x[x.Count / 2]; Median = GetMedian(SortedValues); Q1 = GetMedian(SortedValues.Take(N / 2).ToList()); Q3 = GetMedian(SortedValues.Skip((N + 1) / 2).ToList()); } Min = SortedValues.First(); Max = SortedValues.Last(); InterquartileRange = Q3 - Q1; LowerFence = Q1 - 1.5 * InterquartileRange; UpperFence = Q3 + 1.5 * InterquartileRange; AllOutliers = SortedValues.Where(IsOutlier).ToArray(); LowerOutliers = SortedValues.Where(IsLowerOutlier).ToArray(); UpperOutliers = SortedValues.Where(IsUpperOutlier).ToArray(); }
/// <summary> /// Statistics for [1/X]. If Min is less then or equal to 0, returns null. /// </summary> public Statistics Invert() => CanBeInverted() ? new Statistics(SortedValues.Select(x => 1 / x)) : null;
[PublicAPI] public double CalcCentralMoment(int k) => SortedValues.Average(x => (x - Mean).Pow(k));
[PublicAPI] public double[] WithoutOutliers() => SortedValues.Where(value => !IsOutlier(value)).ToArray();