gitee.com/quant1x/num@v0.3.2/shift.go (about) 1 package num 2 3 import ( 4 "slices" 5 ) 6 7 // Shift 使用可选的时间频率按所需的周期数移动索引 8 // 9 // N 支持前后移动, N>0 向右, N<0 向左 10 func Shift[E BaseType](S []E, N any) []E { 11 return v3Shift[E](S, N) 12 } 13 14 // N为常量常量, 未加速处理, 且做了一次对齐操作 15 func v1Shift[T BaseType](S []T, N any) []T { 16 length := len(S) 17 var _n []DType 18 switch v := N.(type) { 19 case DTypeArray: 20 _n = v.DTypes() 21 case int: 22 if v == 0 { 23 return S 24 } 25 _n = Repeat[DType](DType(v), length) 26 case DType: 27 if v == 0 || DTypeIsNaN(v) { 28 return S 29 } 30 _n = Repeat[DType](DType(v), length) 31 case []int: 32 _n = Slice2DType(v) 33 _n = Align(_n, NaN(), length) 34 case []DType: 35 _n = Align(v, NaN(), length) 36 default: 37 panic(ErrInvalidWindow) 38 } 39 var d []T 40 d = slices.Clone(S) 41 values := d 42 for i, _ := range S { 43 x := _n[i] 44 pos := int(x) 45 if DTypeIsNaN(x) || i-pos >= length || i-pos < 0 { 46 values[i] = TypeDefault[T]() 47 continue 48 } 49 values[i] = S[i-pos] 50 } 51 52 return d 53 } 54 55 // N为常量常量, 未加速处理 56 func v2Shift[E BaseType](S []E, N any) []E { 57 length := len(S) 58 w := Any2Window[DType](N) 59 d := slices.Clone(S) 60 for i, _ := range S { 61 x := w.At(i) 62 pos := int(x) 63 if DTypeIsNaN(x) || i-pos >= length || i-pos < 0 { 64 d[i] = TypeDefault[E]() 65 continue 66 } 67 d[i] = S[i-pos] 68 } 69 return d 70 } 71 72 // N为常量常量, copy处理 73 func v3Shift[E BaseType](S []E, N any) []E { 74 length := len(S) 75 w := Any2Window[DType](N) 76 defaultValue := TypeDefault[E]() 77 d := make([]E, length) 78 if w.IsConst() { 79 // 如果参数是常量 80 n := int(w.C) 81 m := AbsInt(n) 82 if m >= length { 83 // 如果n大于S长度, 则返回空 84 RepeatInto(d, defaultValue, length) 85 return d 86 } 87 // 分两段操作 88 if n > 0 { 89 // 左边留空 90 // 1. copy从n开始的全部数据到目标切片的n 91 copy(d[m:length], S[:length-m]) 92 // 2. 前部0~n赋予默认值 93 RepeatInto[E](d[0:m], defaultValue, m) 94 } else if n < 0 { 95 // 右边留空 96 // 1. copy从0开始的全部数据到目标切片的length-m 97 copy(d[0:length-m], S[m:length]) 98 // 2. 前部length-m~length赋予默认值 99 RepeatInto[E](d[length-m:length], defaultValue, m) 100 } 101 return d 102 } 103 for i, _ := range S { 104 x := w.At(i) 105 pos := int(x) 106 if DTypeIsNaN(x) || i-pos >= length || i-pos < 0 { 107 d[i] = defaultValue 108 continue 109 } 110 d[i] = S[i-pos] 111 } 112 return d 113 } 114 115 // N为常量常量, copy处理, v3的简化版, 可读性不高 116 func v4Shift[E BaseType](S []E, N any) []E { 117 length := len(S) 118 w := Any2Window[DType](N) 119 defaultValue := TypeDefault[E]() 120 d := make([]E, length) 121 if w.IsConst() { 122 // 如果参数是常量 123 n := int(w.C) 124 m := AbsInt(n) 125 if m >= length { 126 // 如果n大于S长度, 则返回空 127 RepeatInto(d, defaultValue, length) 128 return d 129 } 130 pos := 0 131 fixed := 0 132 if n < 0 { 133 pos = m 134 fixed = length - m 135 } 136 // 分两段操作 137 // 1. copy源切片到目标切片 138 copy(d[m-pos:length-pos], S[pos:pos+length-m]) 139 // 2. 空余位置填充默认值 140 RepeatInto[E](d[fixed:fixed+m], defaultValue, m) 141 return d 142 } 143 for i, _ := range S { 144 x := w.At(i) 145 pos := int(x) 146 if DTypeIsNaN(x) || i-pos >= length || i-pos < 0 { 147 d[i] = defaultValue 148 continue 149 } 150 d[i] = S[i-pos] 151 } 152 return d 153 } 154 155 //// ShiftN series切片, 使用可选的时间频率按所需的周期数移动索引 156 //// Deprecated: 不推荐使用 157 //func ShiftN[T BaseType](S []T, periods int) []T { 158 // d := slices.Clone(S) 159 // if periods == 0 { 160 // return d 161 // } 162 // 163 // values := d 164 // var ( 165 // naVals []T 166 // dst []T 167 // src []T 168 // ) 169 // 170 // if shlen := int(math.Abs(float64(periods))); shlen < len(values) { 171 // if periods > 0 { 172 // naVals = values[:shlen] 173 // dst = values[shlen:] 174 // src = values 175 // } else { 176 // naVals = values[len(values)-shlen:] 177 // dst = values[:len(values)-shlen] 178 // src = values[shlen:] 179 // } 180 // copy(dst, src) 181 // } else { 182 // naVals = values 183 // } 184 // for i := range naVals { 185 // naVals[i] = TypeDefault[T]() 186 // } 187 // _ = naVals 188 // return d 189 //}