handle_data.go 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. package models
  2. import (
  3. "errors"
  4. "github.com/shopspring/decimal"
  5. "hongze/hongze_edb_lib/utils"
  6. "math"
  7. "time"
  8. )
  9. // HandleDataByLinearRegression 插值法补充数据(线性方程式)
  10. func HandleDataByLinearRegression(edbInfoDataList []*EdbInfoSearchData, handleDataMap map[string]float64) (err error) {
  11. if len(edbInfoDataList) < 2 {
  12. return
  13. }
  14. var startEdbInfoData *EdbInfoSearchData
  15. for _, v := range edbInfoDataList {
  16. handleDataMap[v.DataTime] = v.Value
  17. // 第一个数据就给过滤了,给后面的试用
  18. if startEdbInfoData == nil {
  19. startEdbInfoData = v
  20. continue
  21. }
  22. // 获取两条数据之间相差的天数
  23. startDataTime, _ := time.ParseInLocation(utils.FormatDate, startEdbInfoData.DataTime, time.Local)
  24. currDataTime, _ := time.ParseInLocation(utils.FormatDate, v.DataTime, time.Local)
  25. betweenHour := int(currDataTime.Sub(startDataTime).Hours())
  26. betweenDay := betweenHour / 24
  27. // 如果相差一天,那么过滤
  28. if betweenDay <= 1 {
  29. startEdbInfoData = v
  30. continue
  31. }
  32. // 生成线性方程式
  33. var a, b float64
  34. {
  35. coordinateData := make([]utils.Coordinate, 0)
  36. tmpCoordinate1 := utils.Coordinate{
  37. X: 1,
  38. Y: startEdbInfoData.Value,
  39. }
  40. coordinateData = append(coordinateData, tmpCoordinate1)
  41. tmpCoordinate2 := utils.Coordinate{
  42. X: float64(betweenDay) + 1,
  43. Y: v.Value,
  44. }
  45. coordinateData = append(coordinateData, tmpCoordinate2)
  46. a, b = utils.GetLinearResult(coordinateData)
  47. if math.IsNaN(a) || math.IsNaN(b) {
  48. err = errors.New("线性方程公式生成失败")
  49. return
  50. }
  51. }
  52. // 生成对应的值
  53. {
  54. for i := 1; i < betweenDay; i++ {
  55. tmpDataTime := startDataTime.AddDate(0, 0, i)
  56. aDecimal := decimal.NewFromFloat(a)
  57. xDecimal := decimal.NewFromInt(int64(i) + 1)
  58. bDecimal := decimal.NewFromFloat(b)
  59. val, _ := aDecimal.Mul(xDecimal).Add(bDecimal).Round(4).Float64()
  60. handleDataMap[tmpDataTime.Format(utils.FormatDate)] = val
  61. }
  62. }
  63. startEdbInfoData = v
  64. }
  65. return
  66. }
  67. // HandleDataByPreviousData 当前日期无值时,用上一个日期的数据补充当前日期的数据
  68. func HandleDataByPreviousData(edbInfoDataList []*EdbInfoSearchData, handleDataMap map[string]float64) (err error) {
  69. if len(edbInfoDataList) < 2 {
  70. return
  71. }
  72. var startEdbInfoData *EdbInfoSearchData
  73. for _, v := range edbInfoDataList {
  74. handleDataMap[v.DataTime] = v.Value
  75. // 第一个数据就给过滤了,给后面的试用
  76. if startEdbInfoData == nil {
  77. startEdbInfoData = v
  78. continue
  79. }
  80. // 获取两条数据之间相差的天数
  81. startDataTime, _ := time.ParseInLocation(utils.FormatDate, startEdbInfoData.DataTime, time.Local)
  82. currDataTime, _ := time.ParseInLocation(utils.FormatDate, v.DataTime, time.Local)
  83. betweenHour := int(currDataTime.Sub(startDataTime).Hours())
  84. betweenDay := betweenHour / 24
  85. // 如果相差一天,那么过滤
  86. if betweenDay <= 1 {
  87. startEdbInfoData = v
  88. continue
  89. }
  90. // 生成对应的值
  91. {
  92. for i := 1; i < betweenDay; i++ {
  93. tmpDataTime := startDataTime.AddDate(0, 0, i)
  94. handleDataMap[tmpDataTime.Format(utils.FormatDate)] = startEdbInfoData.Value
  95. }
  96. }
  97. startEdbInfoData = v
  98. }
  99. return
  100. }