From 57b59079cd554073b26a36c595f8a7198af80b2a Mon Sep 17 00:00:00 2001 From: wangfeng Date: Wed, 1 Feb 2023 14:11:03 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=9E=E7=8E=B0=E4=BA=86rolling=E5=9B=BA?= =?UTF-8?q?=E5=AE=9A=E5=8F=82=E6=95=B0=E7=9A=84=E7=94=A8=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- generic.go | 82 ++++++++++++++++++++++++++++++++++++------ generic_test.go | 12 ++++++- series_ewm.go | 3 +- series_float64_test.go | 2 +- series_int64.go | 6 ++-- series_int64_test.go | 6 ++-- 6 files changed, 93 insertions(+), 18 deletions(-) diff --git a/generic.go b/generic.go index 5edd9d5..13c2534 100644 --- a/generic.go +++ b/generic.go @@ -1,6 +1,8 @@ package pandas import ( + "gitee.com/quant1x/pandas/algorithms/avx2" + "gonum.org/v1/gonum/stat" "reflect" "sync" ) @@ -104,6 +106,14 @@ func Repeat[T GenericType](a T, n int) []T { return dst } +// Repeat2 重复生成a +func Repeat2[T GenericType](dst []T, a T, n int) []T { + for i := 0; i < n; i++ { + dst[i] = a + } + return dst +} + func (self *NDFrame) Name() string { return self.name } @@ -269,26 +279,78 @@ func (self *NDFrame) Subset(start, end int, opt ...any) Series { } func (self *NDFrame) Repeat(x any, repeats int) Series { - //TODO implement me - panic("implement me") + switch values := self.values.(type) { + case []bool: + _ = values + vs := Repeat(AnyToBool(x), repeats) + return NewNDFrame(self.name, vs...) + case []string: + vs := Repeat(AnyToString(x), repeats) + return NewNDFrame(self.name, vs...) + case []int64: + vs := Repeat(AnyToInt64(x), repeats) + return NewNDFrame(self.name, vs...) + default: //case []float64: + vs := Repeat(AnyToFloat64(x), repeats) + return NewNDFrame(self.name, vs...) + } } func (self *NDFrame) Shift(periods int) Series { - //TODO implement me - panic("implement me") + var d Series + d = clone(self).(Series) + //return Shift[float64](&d, periods, func() float64 { + // return Nil2Float + //}) + switch values := self.values.(type) { + case []bool: + _ = values + return Shift[bool](&d, periods, func() bool { + return BoolNaN + }) + case []string: + return Shift[string](&d, periods, func() string { + return StringNaN + }) + case []int64: + return Shift[int64](&d, periods, func() int64 { + return Nil2Int + }) + default: //case []float64: + return Shift[float64](&d, periods, func() float64 { + return Nil2Float + }) + } } func (self *NDFrame) Rolling(window int) RollingWindow { - //TODO implement me - panic("implement me") + return RollingWindow{ + window: window, + series: self, + } } func (self *NDFrame) Mean() float64 { - //TODO implement me - panic("implement me") + if self.Len() < 1 { + return NaN() + } + fs := make([]float64, 0) + self.apply(func(idx int, v any) { + f := AnyToFloat64(v) + fs = append(fs, f) + }) + stdDev := avx2.Mean(fs) + return stdDev } func (self *NDFrame) StdDev() float64 { - //TODO implement me - panic("implement me") + if self.Len() < 1 { + return NaN() + } + values := make([]float64, self.Len()) + self.apply(func(idx int, v any) { + values[idx] = AnyToFloat64(v) + }) + stdDev := stat.StdDev(values, nil) + return stdDev } diff --git a/generic_test.go b/generic_test.go index f17286c..5c5393f 100644 --- a/generic_test.go +++ b/generic_test.go @@ -54,13 +54,23 @@ func TestSeriesFrame(t *testing.T) { func TestNDFrameNew(t *testing.T) { // float64 - d1 := []float64{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, NaN(), 12} + //d1 := []float64{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, NaN(), 12} + d1 := []float64{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12} nd1 := NewNDFrame[float64]("x", d1...) fmt.Println(nd1) fmt.Println(nd1.Records()) nd11 := nd1.Subset(1, 2, true) fmt.Println(nd11.Records()) + nd12 := nd1.Rolling(5).Mean() + d12 := nd12.Values() + fmt.Println(d12) + + nd13 := nd1.Shift(3) + fmt.Println(nd13.Values()) + nd14 := nd1.Rolling(5).StdDev() + fmt.Println(nd14.Values()) + // string d2 := []string{"1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "nan", "12"} nd2 := NewNDFrame[string]("x", d2...) diff --git a/series_ewm.go b/series_ewm.go index e0ee033..4d09adf 100644 --- a/series_ewm.go +++ b/series_ewm.go @@ -21,7 +21,7 @@ const ( AlphaHalflife ) -// EW(Factor) 指数加权(EW)计算Alpha 结构属性非0即为有效启动同名算法 +// EW (Factor) 指数加权(EW)计算Alpha 结构属性非0即为有效启动同名算法 type EW struct { Com float64 // 根据质心指定衰减 Span float64 // 根据跨度指定衰减 @@ -31,6 +31,7 @@ type EW struct { IgnoreNA bool // 计算权重时忽略缺失值 } +// ExponentialMovingWindow 加权移动窗口 type ExponentialMovingWindow struct { data Series // 序列 atype AlphaType // 计算方式: com/span/halflefe/alpha diff --git a/series_float64_test.go b/series_float64_test.go index 75ecdfd..920ca11 100644 --- a/series_float64_test.go +++ b/series_float64_test.go @@ -25,7 +25,7 @@ func TestNewSeriesFloat64(t *testing.T) { fmt.Printf("d4 = %+v\n", d4.Values()) d5 := s4.Rolling(5).StdDev() - fmt.Printf("d4 = %+v\n", d5.Values()) + fmt.Printf("d5 = %+v\n", d5.Values()) s5 := NewSeriesFloat64("x", []float64{1, 2, 3, 4, 5, 6, 7, 8, 9}) diff --git a/series_int64.go b/series_int64.go index eb05719..2f11790 100644 --- a/series_int64.go +++ b/series_int64.go @@ -151,8 +151,10 @@ func (self *SeriesInt64) Subset(start, end int, opt ...any) Series { } func (self *SeriesInt64) Rolling(window int) RollingWindow { - //TODO implement me - panic("implement me") + return RollingWindow{ + window: window, + series: self, + } } func (self *SeriesInt64) Mean() float64 { diff --git a/series_int64_test.go b/series_int64_test.go index 031090c..1dfbe65 100644 --- a/series_int64_test.go +++ b/series_int64_test.go @@ -20,7 +20,7 @@ func TestNewSeriesInt64(t *testing.T) { s3 := s1.Repeat(1, 2) fmt.Println(s3.Values()) - //s4 := NewSeriesInt64("x", []float64{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}) - //d4 := s4.Rolling(5).Mean() - //fmt.Printf("d4 = %+v\n", d4.Values()) + s4 := NewSeriesInt64("x", []float64{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}) + d4 := s4.Rolling(5).Mean() + fmt.Printf("d4 = %+v\n", d4.Values()) } -- Gitee