-
Notifications
You must be signed in to change notification settings - Fork 2
/
window.go
109 lines (83 loc) · 1.74 KB
/
window.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
package series
import (
"sort"
"github.com/WinPooh32/series/math"
)
type Window struct {
len int
data Data
}
func (w Window) Sum() Data {
return w.Apply(Sum)
}
func (w Window) Mean() Data {
return w.Apply(Mean)
}
func (w Window) Min() Data {
return w.Apply(Min)
}
func (w Window) Max() Data {
return w.Apply(Max)
}
func (w Window) Skew(ma Data) Data {
return w.Apply(Skew)
}
func (w Window) Median() Data {
return w.applyMedian()
}
func (w Window) Variance(ma Data, ddof int) Data {
return w.applyVar(Variance, ma, ddof)
}
func (w Window) Std(ma Data, ddof int) Data {
return w.applyVar(Std, ma, ddof)
}
func (w Window) Apply(agg AggregateFunc) Data {
var (
clone = w.data.Clone()
values = clone.Values()
period = w.len
)
for i := 0; i < w.len-1; i++ {
values[i] = math.NaN()
}
w.data.RollData(period, func(l int, r int) {
slice := w.data.Slice(l, r)
values[r-1] = agg(slice)
})
return clone
}
func (w Window) applyVar(varfn func(data Data, mean DType, ddof int) DType, ma Data, ddof int) Data {
var (
clone = w.data.Clone()
values = clone.Values()
period = w.len
)
total := period - 1
for i := total; i < len(values); i++ {
p := i + 1
v := w.data.Slice(p-period, p)
values[i] = varfn(v, ma.values[p-1], ddof)
}
for i := 0; i < total; i++ {
values[i] = math.NaN()
}
return clone
}
func (w Window) applyMedian() Data {
var (
clone = w.data.Clone()
values = clone.Values()
tmp = make([]DType, 0, w.len)
period = w.len
)
for i := 0; i < w.len-1; i++ {
values[i] = math.NaN()
}
w.data.RollData(period, func(l int, r int) {
slice := w.data.Slice(l, r)
tmp = append(tmp[:0], slice.values...)
sort.Sort(DTypeSlice(tmp))
values[r-1] = Median(Data{values: tmp})
})
return clone
}