From 89bfd7c9c7bf3ce9ac15d3b16ecc6e7e8cb4a40c Mon Sep 17 00:00:00 2001 From: wangfeng Date: Sat, 4 Feb 2023 10:53:30 +0800 Subject: [PATCH 01/11] =?UTF-8?q?=E5=A4=87=E6=B3=A8=E6=B3=9B=E5=9E=8B?= =?UTF-8?q?=E6=95=B0=E6=8D=AE=E7=9A=84=E6=89=A9=E5=B1=95=E6=80=A7=E9=97=AE?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frame.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frame.go b/frame.go index a422e79..ae9b41b 100644 --- a/frame.go +++ b/frame.go @@ -16,7 +16,7 @@ type Frame[T GenericType] interface { // Len 获得行数 Len() int // Values 获得全部数据集 - Values() []T + Values() []T // 如果确定类型, 后面可能无法自动调整 } type GenericFrame[T GenericType] struct { -- Gitee From 94270e493ff712a643fc619f5db03d14c817eb5d Mon Sep 17 00:00:00 2001 From: wangfeng Date: Sat, 4 Feb 2023 11:45:40 +0800 Subject: [PATCH 02/11] =?UTF-8?q?=E6=8B=86=E5=88=86rolling=E6=96=B9?= =?UTF-8?q?=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- generic.go | 7 ------- generic_rolling.go | 8 ++++++++ 2 files changed, 8 insertions(+), 7 deletions(-) create mode 100644 generic_rolling.go diff --git a/generic.go b/generic.go index cc04076..427e6f3 100644 --- a/generic.go +++ b/generic.go @@ -231,13 +231,6 @@ func (self *NDFrame) Shift(periods int) Series { } } -func (self *NDFrame) Rolling(window int) RollingWindow { - return RollingWindow{ - window: window, - series: self, - } -} - func (self *NDFrame) Mean() float64 { if self.Len() < 1 { return NaN() diff --git a/generic_rolling.go b/generic_rolling.go new file mode 100644 index 0000000..27ee639 --- /dev/null +++ b/generic_rolling.go @@ -0,0 +1,8 @@ +package pandas + +func (self *NDFrame) Rolling(window int) RollingWindow { + return RollingWindow{ + window: window, + series: self, + } +} -- Gitee From 5ecf3f740c157c1acd102f8892d4d9cd0c7f71e5 Mon Sep 17 00:00:00 2001 From: wangfeng Date: Sat, 4 Feb 2023 13:21:28 +0800 Subject: [PATCH 03/11] =?UTF-8?q?=E9=A2=84=E5=A4=87=E6=89=A9=E5=B1=95?= =?UTF-8?q?=E7=9A=84=E4=BB=A3=E7=A0=81,=20=E5=85=88=E5=8D=A0=E4=B8=AA?= =?UTF-8?q?=E4=BD=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- series_number.go | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/series_number.go b/series_number.go index b87ef2d..a425471 100644 --- a/series_number.go +++ b/series_number.go @@ -159,3 +159,13 @@ func point_to_number[T Number](v any, nil2t T, bool2t func(b bool) T, string2t f } return T(0) } + +//func anyToNumber(v any) int { +// switch val := v.(type) { +// case nil, int8, uint8, int16, uint16, int32, uint32, int64, uint64, int, uint, float32, float64, bool, string: +// // 基础类型 +// series_append(&frame, idx, size, val) +// default: +// } +// return 0 +//} -- Gitee From e4c0bb56f57533730475e4c64ee907348faabb09 Mon Sep 17 00:00:00 2001 From: wangfeng Date: Sat, 4 Feb 2023 15:04:27 +0800 Subject: [PATCH 04/11] =?UTF-8?q?fixed:=20=E4=BF=AE=E5=A4=8D=E6=88=AA?= =?UTF-8?q?=E5=8F=96series=E7=9A=84=E9=95=BF=E5=BA=A6=E9=94=99=E8=AF=AF?= =?UTF-8?q?=E7=9A=84bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- generic_range.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/generic_range.go b/generic_range.go index 649244f..3f97ce8 100644 --- a/generic_range.go +++ b/generic_range.go @@ -26,12 +26,13 @@ func (self *NDFrame) Subset(start, end int, opt ...any) Series { vk := vv.Kind() switch vk { case reflect.Slice, reflect.Array: // 切片和数组同样的处理逻辑 - vs = vv.Slice(start, end).Interface() + vvs := vv.Slice(start, end) + vs = vvs.Interface() rows = vv.Len() if __optCopy && rows > 0 { vs = gc.Clone(vs) } - rows = vv.Len() + rows = vvs.Len() frame := NDFrame{ formatter: self.formatter, name: self.name, -- Gitee From c497612947ebffd0accb9acaf4c46f1a52e3d816 Mon Sep 17 00:00:00 2001 From: wangfeng Date: Sat, 4 Feb 2023 15:05:27 +0800 Subject: [PATCH 05/11] =?UTF-8?q?dataframe=E4=BD=BF=E7=94=A8any=E5=8F=82?= =?UTF-8?q?=E6=95=B0,=20=E5=8E=BB=E6=8E=89=E5=8E=9Fgota=E7=9A=84=E7=94=A8?= =?UTF-8?q?=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dataframe.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/dataframe.go b/dataframe.go index 1f0505c..e2df4d5 100644 --- a/dataframe.go +++ b/dataframe.go @@ -25,13 +25,13 @@ func NewDataFrame(se ...Series) DataFrame { for i, s := range se { var d Series if s.Type() == SERIES_TYPE_INT { - d = NewSeriesInt64(s.Name(), s.Values()) + d = NewSeries(SERIES_TYPE_INT, s.Name(), s.Values()) } else if s.Type() == SERIES_TYPE_BOOL { - d = NewSeriesBool(s.Name(), s.Values()) + d = NewSeries(SERIES_TYPE_BOOL, s.Name(), s.Values()) } else if s.Type() == SERIES_TYPE_STRING { - d = NewSeriesString(s.Name(), s.Values()) + d = NewSeries(SERIES_TYPE_STRING, s.Name(), s.Values()) } else { - d = NewSeriesFloat64(s.Name(), s.Values()) + d = NewSeries(SERIES_TYPE_FLOAT, s.Name(), s.Values()) } columns[i] = d } -- Gitee From 8894812cf1bd9b01b8a2f5e75d8148da89facb81 Mon Sep 17 00:00:00 2001 From: wangfeng Date: Sat, 4 Feb 2023 15:06:00 +0800 Subject: [PATCH 06/11] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E4=B8=80=E4=B8=AA?= =?UTF-8?q?=E5=B8=A6=E9=94=99=E8=AF=AF=E5=8F=B7=E7=9A=84=E5=BC=82=E5=B8=B8?= =?UTF-8?q?=E7=BB=93=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- exception/errors.go | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 exception/errors.go diff --git a/exception/errors.go b/exception/errors.go new file mode 100644 index 0000000..bfcccae --- /dev/null +++ b/exception/errors.go @@ -0,0 +1,29 @@ +package exception + +import "fmt" + +type Throwable interface { + error + Code() int +} + +type Exception struct { + Throwable + code int + message string +} + +func New(code int, message string) *Exception { + return &Exception{ + code: code, + message: message, + } +} + +func (this Exception) Error() string { + return fmt.Sprintf("#%d, message=%s", this.code, this.message) +} + +func (this Exception) Code() int { + return this.code +} -- Gitee From a852dc7d503b45d3ca94b08995a9cb787f01e45f Mon Sep 17 00:00:00 2001 From: wangfeng Date: Sat, 4 Feb 2023 15:06:50 +0800 Subject: [PATCH 07/11] =?UTF-8?q?=E5=A2=9E=E5=8A=A0float32=E5=92=8Cfloat64?= =?UTF-8?q?=E7=9A=84=E6=B3=9B=E5=9E=8Brepeat=E5=87=BD=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- stat/repeat.go | 22 ++++++++++++++++++++++ stat/repeat_test.go | 17 +++++++++++++++++ 2 files changed, 39 insertions(+) create mode 100644 stat/repeat.go create mode 100644 stat/repeat_test.go diff --git a/stat/repeat.go b/stat/repeat.go new file mode 100644 index 0000000..53564e8 --- /dev/null +++ b/stat/repeat.go @@ -0,0 +1,22 @@ +package stat + +import ( + "github.com/viterin/vek" + "github.com/viterin/vek/vek32" + "unsafe" +) + +// Repeat repeat +func Repeat[T Float](f T, n int) []T { + var d any + bitsize := unsafe.Sizeof(f) + if bitsize == 4 { + d = vek32.Repeat(float32(f), n) + } else if bitsize == 8 { + d = vek.Repeat(float64(f), n) + } else { + // 应该不会走到这里 + d = []T{} + } + return d.([]T) +} diff --git a/stat/repeat_test.go b/stat/repeat_test.go new file mode 100644 index 0000000..364a04c --- /dev/null +++ b/stat/repeat_test.go @@ -0,0 +1,17 @@ +package stat + +import ( + "fmt" + "testing" +) + +func TestRepeat(t *testing.T) { + f32 := float32(1) + f64 := float64(1) + + n := 10 + fs32 := Repeat(f32, n) + fmt.Println(fs32) + fs64 := Repeat(f64, n) + fmt.Println(fs64) +} -- Gitee From 91184cd76169a447756fa40a04c1b765ef990c87 Mon Sep 17 00:00:00 2001 From: wangfeng Date: Sat, 4 Feb 2023 15:07:21 +0800 Subject: [PATCH 08/11] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E6=88=AA=E6=96=ADslice?= =?UTF-8?q?=E7=9A=84=E5=88=9D=E5=A7=8B=E5=8C=96bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- stat/align.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/stat/align.go b/stat/align.go index b84e126..83cc768 100644 --- a/stat/align.go +++ b/stat/align.go @@ -1,11 +1,12 @@ package stat -// Data alignment -func align[T StatType](x []T, a T, dLen int) []T { +// Align Data alignment +func Align[T StatType](x []T, a T, dLen int) []T { d := []T{} xLen := len(x) if xLen >= dLen { // 截断 + d = make([]T, dLen) copy(d, x[0:dLen]) } else { // 扩展内存 -- Gitee From f44e1a1a32abeee987feba621b9d83aac08f42e5 Mon Sep 17 00:00:00 2001 From: wangfeng Date: Sat, 4 Feb 2023 15:07:42 +0800 Subject: [PATCH 09/11] =?UTF-8?q?=E5=A2=9E=E5=8A=A0float=E7=9A=84=E6=B3=9B?= =?UTF-8?q?=E5=8C=96=E7=B1=BB=E5=9E=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- stat/type.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/stat/type.go b/stat/type.go index 1229357..3f2a167 100644 --- a/stat/type.go +++ b/stat/type.go @@ -5,6 +5,10 @@ import ( "reflect" ) +type Float interface { + ~float32 | ~float64 +} + type StatType interface { ~int32 | ~int64 | ~float32 | ~float64 } -- Gitee From 5b99bf450a1965b50184bddf3e26474a23fa510e Mon Sep 17 00:00:00 2001 From: wangfeng Date: Sat, 4 Feb 2023 15:08:08 +0800 Subject: [PATCH 10/11] =?UTF-8?q?where=E5=87=BD=E6=95=B0=E8=B0=83=E6=95=B4?= =?UTF-8?q?=E4=B8=BApublic=E5=87=BD=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- stat/where.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/stat/where.go b/stat/where.go index a7d5253..38a1c9b 100644 --- a/stat/where.go +++ b/stat/where.go @@ -30,13 +30,13 @@ func Where[T StatType](condition []T, x, y []T) []T { defaultValue := typeDefault(T(0)) // 对齐所有长度 if clen < maxLength { - condition = align(condition, defaultValue, maxLength) + condition = Align(condition, defaultValue, maxLength) } if xlen < maxLength { - x = align(x, defaultValue, maxLength) + x = Align(x, defaultValue, maxLength) } if ylen < maxLength { - y = align(y, defaultValue, maxLength) + y = Align(y, defaultValue, maxLength) } // 初始化返回值 d := make([]T, maxLength) -- Gitee From 93e09456135e9e5e7a5755f5dddbef8bc0d5158a Mon Sep 17 00:00:00 2001 From: wangfeng Date: Sat, 4 Feb 2023 15:09:35 +0800 Subject: [PATCH 11/11] =?UTF-8?q?#I6BMTE=20=E5=AE=9E=E7=8E=B0=E5=BA=8F?= =?UTF-8?q?=E5=88=97=E6=8D=A2=E7=9A=84rolling?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- generic_rolling.go | 58 ++++++++++++++++++++++++++++++++++++++++++++++ generic_test.go | 19 +++++++++++++++ series.go | 2 ++ 3 files changed, 79 insertions(+) diff --git a/generic_rolling.go b/generic_rolling.go index 27ee639..1859108 100644 --- a/generic_rolling.go +++ b/generic_rolling.go @@ -1,8 +1,66 @@ package pandas +import ( + "gitee.com/quant1x/pandas/exception" + "gitee.com/quant1x/pandas/stat" +) + +// Rolling 滑动窗口 func (self *NDFrame) Rolling(window int) RollingWindow { return RollingWindow{ window: window, series: self, } } + +// RollingAndExpandingMixin 滚动和扩展静态横切 +type RollingAndExpandingMixin struct { + window []float32 + series Series +} + +// Rolling2 RollingAndExpandingMixin +func (self *NDFrame) Rolling2(param any) RollingAndExpandingMixin { + var N []float32 + switch v := param.(type) { + case int: + N = stat.Repeat[float32](float32(v), self.Len()) + case Series: + vs := v.Values() + N = sliceToFloat32(vs) + N = stat.Align(N, Nil2Float32, self.Len()) + default: + panic(exception.New(1, "error window")) + } + w := RollingAndExpandingMixin{ + window: N, + series: self, + } + return w +} + +func (r RollingAndExpandingMixin) getBlocks() (blocks []Series) { + for i := 0; i < r.series.Len(); i++ { + N := r.window[i] + if Float32IsNaN(N) || int(N) > i+1 { + blocks = append(blocks, r.series.Empty()) + continue + } + window := int(N) + start := i + 1 - window + end := i + 1 + blocks = append(blocks, r.series.Subset(start, end)) + } + + return +} + +// Mean returns the rolling mean. +func (r RollingAndExpandingMixin) Mean() (s Series) { + var d []float64 + for _, block := range r.getBlocks() { + d = append(d, block.Mean()) + } + s = NewSeries(SERIES_TYPE_FLOAT, r.series.Name(), d) + return +} diff --git a/generic_test.go b/generic_test.go index fda2edb..2a25749 100644 --- a/generic_test.go +++ b/generic_test.go @@ -65,3 +65,22 @@ func TestNDFrameNew(t *testing.T) { fmt.Println(nd2.Records()) fmt.Println(nd2.Empty()) } + +func TestRolling2(t *testing.T) { + d1 := []float64{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12} + s1 := NewNDFrame[float64]("x", d1...) + df := NewDataFrame(s1) + fmt.Println(df) + fmt.Println("------------------------------------------------------------") + + N := 5 + fmt.Println("固定的参数, N =", N) + r1 := df.Col("x").Rolling2(5).Mean().Values() + fmt.Println("序列化结果:", r1) + fmt.Println("------------------------------------------------------------") + d2 := []float64{1, 2, 3, 4, 3, 3, 2, 1, Nil2Float64, Nil2Float64, Nil2Float64, Nil2Float64} + s2 := NewSeries(SERIES_TYPE_FLOAT, "x", d2) + fmt.Printf("序列化参数: %+v\n", s2.Values()) + r2 := df.Col("x").Rolling2(s2).Mean().Values() + fmt.Println("序列化结果:", r2) +} diff --git a/series.go b/series.go index 2cb8507..397d938 100644 --- a/series.go +++ b/series.go @@ -59,6 +59,8 @@ type Series interface { Shift(periods int) Series // Rolling creates new RollingWindow Rolling(window int) RollingWindow + // Rolling2 序列化版本 + Rolling2(param any) RollingAndExpandingMixin // Mean calculates the average value of a series Mean() float64 // StdDev calculates the standard deviation of a series -- Gitee