| | |
| | | using DevExpress.Utils; |
| | | using DevExpress.CodeParser; |
| | | using DevExpress.Utils; |
| | | using DevExpress.XtraCharts; |
| | | using System.Linq; |
| | | using Yw.WinFrmUI.Phart; |
| | | |
| | | namespace PBS.WinFrmUI.Hydro |
| | |
| | | foreach (var item in waterPointGroup) |
| | | { |
| | | var x = item.Key; |
| | | var yList = item.Select(x => x.EndPressure).OrderBy(x => x).ToList(); |
| | | var list = item.Select(t => new Yw.Geometry.Point2d(x, t.EndPressure)).ToList(); |
| | | |
| | | var yUpper = CalculatePercentile(yList, 0.95); |
| | | var yLower = CalculatePercentile(yList, 0.05); |
| | | var yNumList = yList.Where(x => x >= yLower && x <= yUpper); |
| | | if (yNumList == null || !yNumList.Any()) |
| | | //var yList = item.Select(x => x.EndPressure).OrderBy(x => x).ToList(); |
| | | |
| | | //var yUpper = CalculatePercentile(yList, 0.95); |
| | | //var yLower = CalculatePercentile(yList, 0.05); |
| | | //var yNumList = yList.Where(x => x >= yLower && x <= yUpper); |
| | | //if (yNumList == null || !yNumList.Any()) |
| | | //{ |
| | | // continue; |
| | | //} |
| | | //var yAverage = yNumList.Where(x => x >= yLower && x <= yUpper).Average(); |
| | | |
| | | //upperPressurePtList.Add(new Yw.Geometry.Point2d(x, yUpper)); |
| | | //lowerPressurePtList.Add(new Yw.Geometry.Point2d(x, yLower)); |
| | | //averagePressurePtList.Add(new Yw.Geometry.Point2d(x, yAverage)); |
| | | |
| | | var fList = DynamicThresholdProcessor.FilterWithDynamicSigma(list); |
| | | // var fList = FilterByStdDev(list); |
| | | if (fList == null || !fList.Any()) |
| | | { |
| | | continue; |
| | | } |
| | | var yAverage = yNumList.Where(x => x >= yLower && x <= yUpper).Average(); |
| | | |
| | | var yUpper = fList.Max(x => x.Y); |
| | | var yLower = fList.Min(x => x.Y); |
| | | var yAverage = fList.Average(x => x.Y); |
| | | |
| | | upperPressurePtList.Add(new Yw.Geometry.Point2d(x, yUpper)); |
| | | lowerPressurePtList.Add(new Yw.Geometry.Point2d(x, yLower)); |
| | | averagePressurePtList.Add(new Yw.Geometry.Point2d(x, yAverage)); |
| | | |
| | | |
| | | } |
| | | |
| | | if (averagePressurePtList.Count > 4) |
| | |
| | | return sortedData[lower] * (1 - fraction) + sortedData[upper] * fraction; |
| | | } |
| | | |
| | | |
| | | public List<Yw.Geometry.Point2d> FilterByStdDev(List<Yw.Geometry.Point2d> group) |
| | | { |
| | | |
| | | var filteredData = new List<Yw.Geometry.Point2d>(); |
| | | |
| | | |
| | | // 小样本数据不处理(阈值设为10) |
| | | if (group.Count() < 3) |
| | | { |
| | | filteredData.AddRange(group); |
| | | return default; |
| | | } |
| | | |
| | | // 计算统计量 |
| | | var pressures = group.Select(p => p.Y).ToList(); |
| | | double mean = pressures.Average(); |
| | | double stdDev = CalculateSampleStdDev(pressures); // 样本标准差 |
| | | |
| | | // 设置3σ边界[1,3,4](@ref) |
| | | double lowerBound = mean - 3 * stdDev; |
| | | double upperBound = mean + 3 * stdDev; |
| | | |
| | | // 过滤异常值 |
| | | filteredData.AddRange( |
| | | group.Where(p => p.Y >= lowerBound && p.Y <= upperBound) |
| | | ); |
| | | |
| | | |
| | | return filteredData; |
| | | } |
| | | |
| | | // 样本标准差计算(n-1)[7,8](@ref) |
| | | private double CalculateSampleStdDev(List<double> values) |
| | | { |
| | | if (values.Count < 2) return 0; |
| | | |
| | | double mean = values.Average(); |
| | | double sumSquares = values.Sum(v => Math.Pow(v - mean, 2)); |
| | | return Math.Sqrt(sumSquares / (values.Count - 1)); |
| | | } |
| | | |
| | | #region Set Axis |
| | | |
| | | |