diff --git a/formula/llvbars.go b/formula/llvbars.go new file mode 100644 index 0000000000000000000000000000000000000000..81ce4de8da0c8882093e68829af710cf3eee1391 --- /dev/null +++ b/formula/llvbars.go @@ -0,0 +1,16 @@ +package formula + +import "gitee.com/quant1x/pandas/stat" + +// LLVBARS 求上一低点到当前的周期数. +// +// 用法: +// LLVBARS(X,N):求N周期内X最低值到当前周期数,N=0表示从第一个有效值开始统计 +// 例如: +// LLVBARS(HIGH,20)求得20日最低点到当前的周期数 +func LLVBARS(S stat.Series, N any) stat.Series { + x := S.Rolling(N).Apply(func(X stat.Series, W stat.DType) stat.DType { + return stat.Any2DType(X.Reverse().ArgMin()) + }) + return x +} diff --git a/formula/llvbars_test.go b/formula/llvbars_test.go new file mode 100644 index 0000000000000000000000000000000000000000..b0110541cc3f87511734c0a30c4cd8965df6e253 --- /dev/null +++ b/formula/llvbars_test.go @@ -0,0 +1,13 @@ +package formula + +import ( + "fmt" + "gitee.com/quant1x/pandas/stat" + "testing" +) + +func TestLLVBARS(t *testing.T) { + n1 := []float32{1.1, 2.2, 1.3, 1.4} + s1 := stat.NewSeries[float32](n1...) + fmt.Println(LLVBARS(s1, 2)) +} diff --git a/generic.go b/series.go similarity index 100% rename from generic.go rename to series.go diff --git a/generic_append.go b/series_append.go similarity index 69% rename from generic_append.go rename to series_append.go index 159370803d4850661ed768cc6a585f49a1bd7e89..f8351d8bf847c20b5c2f004824b575f47d51f658 100644 --- a/generic_append.go +++ b/series_append.go @@ -5,6 +5,28 @@ import ( "reflect" ) +func (self *NDFrame) Reverse() stat.Series { + s := self.Empty() + + if self.type_ == stat.SERIES_TYPE_BOOL { + values := stat.Reverse(self.values.([]bool)) + s = s.Append(values) + } else if self.type_ == stat.SERIES_TYPE_INT64 { + values := stat.Reverse(self.values.([]int64)) + s = s.Append(values) + } else if self.type_ == stat.SERIES_TYPE_FLOAT32 { + values := stat.Reverse(self.values.([]float32)) + s = s.Append(values) + } else if self.type_ == stat.SERIES_TYPE_FLOAT64 { + values := stat.Reverse(self.values.([]float64)) + s = s.Append(values) + } else { + values := stat.Reverse(self.values.([]string)) + s = s.Append(values) + } + return s +} + // 插入一条记录 func (self *NDFrame) insert(idx, size int, v any) { if self.type_ == stat.SERIES_TYPE_BOOL { diff --git a/generic_apply.go b/series_apply.go similarity index 100% rename from generic_apply.go rename to series_apply.go diff --git a/generic_diff.go b/series_diff.go similarity index 100% rename from generic_diff.go rename to series_diff.go diff --git a/generic_diff_test.go b/series_diff_test.go similarity index 100% rename from generic_diff_test.go rename to series_diff_test.go diff --git a/generic_ewm.go b/series_ewm.go similarity index 100% rename from generic_ewm.go rename to series_ewm.go diff --git a/generic_fillna.go b/series_fillna.go similarity index 100% rename from generic_fillna.go rename to series_fillna.go diff --git a/generic_max.go b/series_max.go similarity index 95% rename from generic_max.go rename to series_max.go index 5f825b8de07fe20c71ec9eb9aa2d81d1741b9a7c..0594dff89c6539c4c6d9418590ef0aa09868ac63 100644 --- a/generic_max.go +++ b/series_max.go @@ -111,3 +111,7 @@ func (self *NDFrame) Max() any { } //return Nil2Float64 } + +func (self *NDFrame) ArgMax() int { + return stat.ArgMax2(self.DTypes()) +} diff --git a/generic_min.go b/series_min.go similarity index 96% rename from generic_min.go rename to series_min.go index c4f4b7728e1cb3e3f66b75d5b100617061340d96..5f978d4992c4e72124525c28a6c053dabebf663a 100644 --- a/generic_min.go +++ b/series_min.go @@ -117,3 +117,7 @@ func (self *NDFrame) Min() any { } return stat.Nil2Float64 } + +func (self *NDFrame) ArgMin() int { + return stat.ArgMin2(self.DTypes()) +} diff --git a/generic_range.go b/series_range.go similarity index 100% rename from generic_range.go rename to series_range.go diff --git a/generic_ref.go b/series_ref.go similarity index 100% rename from generic_ref.go rename to series_ref.go diff --git a/generic_rolling.go b/series_rolling.go similarity index 100% rename from generic_rolling.go rename to series_rolling.go diff --git a/generic_shift.go b/series_shift.go similarity index 100% rename from generic_shift.go rename to series_shift.go diff --git a/generic_sort.go b/series_sort.go similarity index 100% rename from generic_sort.go rename to series_sort.go diff --git a/generic_sum.go b/series_sum.go similarity index 100% rename from generic_sum.go rename to series_sum.go diff --git a/generic_test.go b/series_test.go similarity index 100% rename from generic_test.go rename to series_test.go diff --git a/series_string.go b/series_xstring.go similarity index 100% rename from series_string.go rename to series_xstring.go diff --git a/series_string_test.go b/series_xstring_test.go similarity index 100% rename from series_string_test.go rename to series_xstring_test.go diff --git a/stat/argmax.go b/stat/argmax.go index d93ce10c4de593b4af28a58f68147cf3594e419b..00239263f6be376bb85b66f101bcae6419faae21 100644 --- a/stat/argmax.go +++ b/stat/argmax.go @@ -6,20 +6,55 @@ import ( ) // ArgMax Returns the indices of the maximum values along an axis. -// 返回轴上最大值的索引 -//func ArgMax_V1[T Number](v []T) int { -// var vv any = v -// switch values := vv.(type) { -// case []float32: -// return vek32.ArgMax(values) -// case []float64: -// return vek.ArgMax(values) -// default: -// return __arg_max(v) -// } -//} +// +// 返回轴上最大值的索引 +func ArgMax[T Number](x []T) int { + ret := unaryOperations2[T, int](x, vek32.ArgMax, vek.ArgMax, __arg_max_go[T]) + return ret +} -func __arg_max_go[T Number](x []T) int { +func ArgMax2[T BaseType](x []T) int { + var d int + switch vs := any(x).(type) { + case []float32: + d = ArgMax(vs) + case []float64: + d = ArgMax(vs) + case []int: + d = ArgMax(vs) + case []int8: + d = ArgMax(vs) + case []int16: + d = ArgMax(vs) + case []int32: + d = ArgMax(vs) + case []int64: + d = ArgMax(vs) + case []uint: + d = ArgMax(vs) + case []uint8: + d = ArgMax(vs) + case []uint16: + d = ArgMax(vs) + case []uint32: + d = ArgMax(vs) + case []uint64: + d = ArgMax(vs) + case []uintptr: + d = ArgMax(vs) + case []string: + d = __arg_max_go(vs) + case []bool: + d = __arg_max_go_bool(vs) + default: + // 其它类型原样返回 + panic(Throw(any(x))) + } + + return d +} + +func __arg_max_go[T Ordered](x []T) int { max := x[0] idx := 0 for i, v := range x[1:] { @@ -31,10 +66,14 @@ func __arg_max_go[T Number](x []T) int { return idx } -// ArgMax Returns the indices of the maximum values along an axis. -// -// 返回轴上最大值的索引 -func ArgMax[T Number](x []T) int { - ret := unaryOperations2[T, int](x, vek32.ArgMax, vek.ArgMax, __arg_max_go[T]) - return ret +func __arg_max_go_bool(x []bool) int { + max := bool2Int(x[0]) + idx := 0 + for i, v := range x[1:] { + if bool2Int(v) > max { + max = bool2Int(v) + idx = 1 + i + } + } + return idx } diff --git a/stat/argmax_test.go b/stat/argmax_test.go index c7800019b975e866a60b826f92fd8dcbda0e1be1..8046e4f7116e3a55246c238cbb4e0c517a7fecb8 100644 --- a/stat/argmax_test.go +++ b/stat/argmax_test.go @@ -9,7 +9,7 @@ func TestArgMax(t *testing.T) { n1 := []float32{1.1, 2.2, 1.3, 1.4} n2 := []float64{1.2, 1.2, 3.3} n3 := []int64{11, 12, 33} - fmt.Println(ArgMax(n1)) - fmt.Println(ArgMax(n2)) - fmt.Println(ArgMax(n3)) + fmt.Println(ArgMax2(n1)) + fmt.Println(ArgMax2(n2)) + fmt.Println(ArgMax2(n3)) } diff --git a/stat/argmin.go b/stat/argmin.go index 82c7a8ce52cdd4dcc45b239fccc9d1dfd29c4941..d77e568ec43fde056da55955ee17682f17c13636 100644 --- a/stat/argmin.go +++ b/stat/argmin.go @@ -13,19 +13,48 @@ func ArgMin[T Number](x []T) int { return ret } -//func ArgMin[T Number](v []T) int { -// var vv any = v -// switch values := vv.(type) { -// case []float32: -// return vek32.ArgMin(values) -// case []float64: -// return vek.ArgMin(values) -// default: -// return __arg_min(v) -// } -//} +func ArgMin2[T BaseType](x []T) int { + var d int + switch vs := any(x).(type) { + case []float32: + d = ArgMin(vs) + case []float64: + d = ArgMin(vs) + case []int: + d = ArgMin(vs) + case []int8: + d = ArgMin(vs) + case []int16: + d = ArgMin(vs) + case []int32: + d = ArgMin(vs) + case []int64: + d = ArgMin(vs) + case []uint: + d = ArgMin(vs) + case []uint8: + d = ArgMin(vs) + case []uint16: + d = ArgMin(vs) + case []uint32: + d = ArgMin(vs) + case []uint64: + d = ArgMin(vs) + case []uintptr: + d = ArgMin(vs) + case []string: + d = __arg_min_go(vs) + case []bool: + d = __arg_min_go_bool(vs) + default: + // 其它类型原样返回 + panic(Throw(any(x))) + } + + return d +} -func __arg_min_go[T Number](x []T) int { +func __arg_min_go[T Ordered](x []T) int { min := x[0] idx := 0 for i, v := range x[1:] { @@ -36,3 +65,15 @@ func __arg_min_go[T Number](x []T) int { } return idx } + +func __arg_min_go_bool(x []bool) int { + min := bool2Int(x[0]) + idx := 0 + for i, v := range x[1:] { + if bool2Int(v) < min { + min = bool2Int(v) + idx = 1 + i + } + } + return idx +} diff --git a/stat/argmin_test.go b/stat/argmin_test.go index e7809832a14b829ed410a91ab5b64a1ec9be09b3..6ebfdebfe1101a360e6ad9eebdacc8dc20e0a8d4 100644 --- a/stat/argmin_test.go +++ b/stat/argmin_test.go @@ -10,8 +10,8 @@ func TestArgMin(t *testing.T) { n2 := []float64{1.2, 1.2, 0.3} n3 := []int64{11, 12, 33} n4 := []int32{55, 11, 12, 33} - fmt.Println(ArgMin(n1)) - fmt.Println(ArgMin(n2)) - fmt.Println(ArgMin(n3)) - fmt.Println(ArgMin(n4)) + fmt.Println(ArgMin2(n1)) + fmt.Println(ArgMin2(n2)) + fmt.Println(ArgMin2(n3)) + fmt.Println(ArgMin2(n4)) } diff --git a/stat/window_ewm.go b/stat/ewm.go similarity index 100% rename from stat/window_ewm.go rename to stat/ewm.go diff --git a/stat/ndarray.go b/stat/ndarray.go index 096b68c12c6938bbf422781d75c1c35265aefa41..eccaba2fa447b4590b6638329d8c570ded0198bd 100644 --- a/stat/ndarray.go +++ b/stat/ndarray.go @@ -8,22 +8,6 @@ import ( type NDArray[T BaseType] []T -func (self NDArray[T]) Name() string { - return "x" -} - -func (self NDArray[T]) Rename(name string) { - -} - -func (self NDArray[T]) Type() Type { - return checkoutRawType(self) -} - -func (self NDArray[T]) Values() any { - return []T(self) -} - func (self NDArray[T]) NaN() any { switch any(self).(type) { case []bool: @@ -153,7 +137,7 @@ func (self NDArray[T]) FillNa(v any, inplace bool) Series { } func (self NDArray[T]) Max() any { - d := Min2(self) + d := Max2(self) return d } diff --git a/stat/ndarray_basic.go b/stat/ndarray_basic.go new file mode 100644 index 0000000000000000000000000000000000000000..fb8f375fc9a486bc953f6a8e38600470b8ed9196 --- /dev/null +++ b/stat/ndarray_basic.go @@ -0,0 +1,21 @@ +package stat + +func (self NDArray[T]) Name() string { + return "x" +} + +func (self NDArray[T]) Rename(name string) { + +} + +func (self NDArray[T]) Type() Type { + return checkoutRawType(self) +} + +func (self NDArray[T]) Values() any { + return []T(self) +} + +func (self NDArray[T]) Reverse() Series { + return Reverse(self) +} diff --git a/stat/ndarray_fromnumeric.go b/stat/ndarray_fromnumeric.go new file mode 100644 index 0000000000000000000000000000000000000000..ef7c449d089a3ae729365f06fa971f489ab4b2e6 --- /dev/null +++ b/stat/ndarray_fromnumeric.go @@ -0,0 +1,9 @@ +package stat + +func (self NDArray[T]) ArgMax() int { + return ArgMax2(self) +} + +func (self NDArray[T]) ArgMin() int { + return ArgMin2(self) +} diff --git a/stat/series.go b/stat/series.go index b0447cb5a491a53f1b608805f98db63b14bc6f3f..990d0b8b37c5c14cd8f474fda38086454f417b46 100644 --- a/stat/series.go +++ b/stat/series.go @@ -16,6 +16,9 @@ type Series interface { // Values 获得全部数据集 Values() any + // Reverse 序列反转 + Reverse() Series + // NaN 输出默认的NaN NaN() any // Floats 强制转成[]float32 @@ -57,8 +60,12 @@ type Series interface { FillNa(v any, inplace bool) Series // Max 找出最大值 Max() any + // ArgMax Returns the indices of the maximum values along an axis + ArgMax() int // Min 找出最小值 Min() any + // ArgMin Returns the indices of the minimum values along an axis + ArgMin() int // Select 选取一段记录 Select(r ScopeLimit) Series // Append 增加一批记录 diff --git a/stat/type.go b/stat/type.go index 8c896f3efa24621fb9bf14cf725378540490aa59..a239602064bf02fb376b5bf5b045ebe9f3d87ce8 100644 --- a/stat/type.go +++ b/stat/type.go @@ -208,7 +208,6 @@ func __anyToNumber[T Number](v any) T { vt := ParseFloat64(val, v) if Float64IsNaN(vt) { td := T(0) - //rawType :=checkoutRawType(td) if !reflect.ValueOf(td).CanFloat() { return td } diff --git a/stat/zeros.go b/stat/zeros.go index 68844b221da3a015d57d51f2eb25babbaa9a4ff2..68a460b501ddcfae04cbc1766f2244c4cc74538a 100644 --- a/stat/zeros.go +++ b/stat/zeros.go @@ -4,19 +4,6 @@ package stat // // args[0] dtype 基础数据类型 func Zeros[T BaseType](shape int) []T { - //var __dtype reflect.Kind = reflect.Invalid - //if len(args) > 0 { - // // 第一个参数为是否copy - // if _cp, ok := args[0].(reflect.Kind); ok { - // __dtype = _cp - // } - //} - //switch __dtype { - //case reflect.Invalid: - //case reflect.Int: - // - //default: - //} var t T return Repeat(t, shape) }