polars-ta 0.5.2__py3-none-any.whl → 0.5.4__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
polars_ta/_version.py CHANGED
@@ -1 +1 @@
1
- __version__ = "0.5.2"
1
+ __version__ = "0.5.4"
@@ -0,0 +1 @@
1
+ from polars_ta.labels.future import * # noqa
@@ -0,0 +1,40 @@
1
+ import numpy as np
2
+ from numba import jit
3
+ from numpy import full
4
+
5
+
6
+ @jit(nopython=True, nogil=True, cache=True)
7
+ def _triple_barrier(close: np.ndarray, high: np.ndarray, low: np.ndarray, window: int, take_profit: float, stop_loss: float) -> np.ndarray:
8
+ """三重障碍打标法"""
9
+ out = full(close.shape[0], np.nan, dtype=np.float64)
10
+ for i in range(close.shape[0] - window + 1):
11
+ entry_price = close[i]
12
+ if np.isnan(entry_price):
13
+ # out[i] = 0
14
+ continue
15
+ upper_barrier = entry_price * (1 + take_profit)
16
+ lower_barrier = entry_price * (1 - stop_loss)
17
+ for j in range(i + 1, i + window):
18
+ hit_upper = high[j] >= upper_barrier
19
+ hit_lower = low[j] <= lower_barrier
20
+ if hit_upper and hit_lower:
21
+ # TODO 同一天无法知道是先触发止损还是先触发止盈
22
+ # 1. 假定离收盘价远的先触发
23
+ if high[j] - close[j] > close[j] - low[j]:
24
+ out[i] = 1 # 最高价更远,触发止盈
25
+ else:
26
+ out[i] = -1 # 最低价更远,触发止损
27
+
28
+ # out[i] = -1 # 2. 简化处理认为先触发止损
29
+ break
30
+ if hit_upper:
31
+ out[i] = 1 # 止盈
32
+ break
33
+ if hit_lower:
34
+ out[i] = -1 # 止损
35
+ break
36
+ else:
37
+ # out[i] = 0 # 1. 时间到了触发平仓
38
+ out[i] = np.sign(close[j] / entry_price - 1) # 2. 时间到了触发平仓
39
+
40
+ return out
@@ -0,0 +1,165 @@
1
+ """
2
+
3
+ 由于标签的定义比较灵活,所以以下代码主要用于参考
4
+
5
+ Notes
6
+ -----
7
+ 标签都是未来数据,在机器学习中,只能用于`y`,不能用于`X`。
8
+
9
+ References
10
+ ----------
11
+ https://mp.weixin.qq.com/s/XtgYezFsslOfW-QyIMr0VA
12
+ https://github.com/Rachnog/Advanced-Deep-Trading/blob/master/bars-labels-diff/Labeling.ipynb
13
+
14
+ """
15
+ from polars import Expr, struct
16
+
17
+ from polars_ta.labels._nb import _triple_barrier
18
+ from polars_ta.utils.numba_ import batches_i2_o1, struct_to_numpy
19
+ from polars_ta.wq import cut, ts_delay, ts_log_diff, log
20
+
21
+
22
+ def ts_log_return(close: Expr, n: int = 5) -> Expr:
23
+ """将未来数据当成卖出价后移到买入价位置,计算对数收益率
24
+
25
+ Examples
26
+ --------
27
+ ```python
28
+ df = pl.DataFrame({
29
+ 'a': [None, 10, 11, 12, 9, 12, 13],
30
+ }).with_columns(
31
+ out1=ts_log_return(pl.col('a'), 3),
32
+ out2=_ts_log_return(pl.col('a'), 3),
33
+ )
34
+
35
+ shape: (7, 3)
36
+ ┌──────┬───────────┬───────────┐
37
+ │ a ┆ out1 ┆ out2 │
38
+ │ --- ┆ --- ┆ --- │
39
+ │ i64 ┆ f64 ┆ f64 │
40
+ ╞══════╪═══════════╪═══════════╡
41
+ │ null ┆ null ┆ null │
42
+ │ 10 ┆ -0.105361 ┆ -0.105361 │
43
+ │ 11 ┆ 0.087011 ┆ 0.087011 │
44
+ │ 12 ┆ 0.080043 ┆ 0.080043 │
45
+ │ 9 ┆ null ┆ null │
46
+ │ 12 ┆ null ┆ null │
47
+ │ 13 ┆ null ┆ null │
48
+ └──────┴───────────┴───────────┘
49
+ ```
50
+
51
+ """
52
+ # return (close.shift(-n) / close).log()
53
+ return log(ts_delay(close, -n) / close)
54
+
55
+
56
+ def _ts_log_return(close: Expr, n: int = 5) -> Expr:
57
+ """计算对数收益率,但将结果后移
58
+
59
+ 如果打标签方式复杂,这种最终结果后移的方法更方便
60
+ """
61
+ # return (close / close.shift(n)).log().shift(-n)
62
+ return ts_delay(ts_log_diff(close, n), -n)
63
+
64
+
65
+ def ts_simple_return(close: Expr, n: int = 5, threshold: float = 0.0, *more_threshold) -> Expr:
66
+ """简单收益率标签。支持二分类、三分类等。对收益率使用`cut`进行分类
67
+
68
+ Parameters
69
+ ----------
70
+ close
71
+ n:int
72
+ 未来n天
73
+ threshold:float
74
+ 收益率阈值,小于该值为0,大于等于该值为1
75
+ more_threshold:float
76
+ 更多的阈值,用于三分类等。小于该值为1,大于等于该值为2,以此类推
77
+
78
+ Returns
79
+ -------
80
+ Expr
81
+ 标签列, 类型为UInt32, 取值为0, 1, 2, ...
82
+
83
+ Examples
84
+ --------
85
+ ```python
86
+ df = pl.DataFrame({
87
+ 'a': [None, 10., 9.99, 9., 10., 11., 11.],
88
+ }).with_columns(
89
+ out1=label_simple_return(pl.col('a'), 1, 0),
90
+ out2=label_simple_return(pl.col('a'), 1, -0.001, 0.001),
91
+ )
92
+
93
+ shape: (7, 3)
94
+ ┌──────┬──────┬──────┐
95
+ │ a ┆ out1 ┆ out2 │
96
+ │ --- ┆ --- ┆ --- │
97
+ │ f64 ┆ u32 ┆ u32 │
98
+ ╞══════╪══════╪══════╡
99
+ │ null ┆ null ┆ null │
100
+ │ 10.0 ┆ 0 ┆ 0 │
101
+ │ 9.99 ┆ 0 ┆ 0 │
102
+ │ 9.0 ┆ 1 ┆ 2 │
103
+ │ 10.0 ┆ 1 ┆ 2 │
104
+ │ 11.0 ┆ 0 ┆ 1 │
105
+ │ 11.0 ┆ null ┆ null │
106
+ └──────┴──────┴──────┘
107
+
108
+ """
109
+ return cut(close.pct_change(n).shift(-n), threshold, *more_threshold)
110
+
111
+
112
+ def ts_triple_barrier(close: Expr, high: Expr, low: Expr, d: int = 5, take_profit: float = 0.1, stop_loss: float = 0.05) -> Expr:
113
+ """三重障碍打标法
114
+
115
+ Parameters
116
+ ----------
117
+ close:Expr
118
+ 收盘价
119
+ high:Expr
120
+ 最高价
121
+ low:Expr
122
+ 最低价
123
+ d:int
124
+ 时间窗口
125
+ take_profit:float
126
+ 止盈比例
127
+ stop_loss:float
128
+ 止损比例
129
+
130
+ Returns
131
+ -------
132
+ Expr
133
+ 标签列。取值为-1止损, 1止盈,0时间到期
134
+
135
+ Notes
136
+ -----
137
+ 1. `high`, `low`在粗略情况下可用`close`代替
138
+ 2. 时间到期时,根据盈亏返回不同的标签
139
+
140
+ Examples
141
+ --------
142
+ ```python
143
+ df = pl.DataFrame({
144
+ "close": [np.nan, 1, 1, 1.0],
145
+ "high": [np.nan, 1, 1.1, 1],
146
+ "low": [np.nan, 1, 1, 0.95],
147
+ }).with_columns(
148
+ out=ts_triple_barrier(pl.col("close"), pl.col("high"), pl.col("low"), 2, 0.1, 0.05)
149
+ )
150
+
151
+ shape: (4, 4)
152
+ ┌───────┬──────┬──────┬──────┐
153
+ │ close ┆ high ┆ low ┆ out │
154
+ │ --- ┆ --- ┆ --- ┆ --- │
155
+ │ f64 ┆ f64 ┆ f64 ┆ f64 │
156
+ ╞═══════╪══════╪══════╪══════╡
157
+ │ NaN ┆ NaN ┆ NaN ┆ null │
158
+ │ 1.0 ┆ 1.0 ┆ 1.0 ┆ 1.0 │
159
+ │ 1.0 ┆ 1.1 ┆ 1.0 ┆ -1.0 │
160
+ │ 1.0 ┆ 1.0 ┆ 0.95 ┆ null │
161
+ └───────┴──────┴──────┴──────┘
162
+ ```
163
+
164
+ """
165
+ return struct([close, high, low]).map_batches(lambda xx: batches_i2_o1(struct_to_numpy(xx, 3), _triple_barrier, d, take_profit, stop_loss))
@@ -1,12 +1,6 @@
1
1
  from polars import Expr
2
2
 
3
- from polars_ta.wq.arithmetic import log1p, expm1 # noqa
4
- # log return
5
- # 对数收益
6
- from polars_ta.wq.time_series import ts_log_diff as ts_log_return # noqa
7
- # simple percentage return
8
- # 简单收益
9
- from polars_ta.wq.time_series import ts_returns as ts_percent_return # noqa
3
+ from polars_ta.wq.arithmetic import log1p, expm1
10
4
 
11
5
 
12
6
  def ts_cum_return(close: Expr) -> Expr:
@@ -0,0 +1 @@
1
+ from polars_ta.labels import * # noqa
polars_ta/ta/README.md ADDED
@@ -0,0 +1,12 @@
1
+ # polars_ta.ta
2
+
3
+ 1. Files in this folder mimic `talib`, and implement `polars` versions for the same functions
4
+ 2. Since we reduce the functino calls between `Python` and `C` code, it should be faster than `talib`.
5
+ 3. We first try to import from `ta`, then from `wq`, and only implement the function if it is not available.
6
+ 4. When there is a circular dependency, we use `polars` instead.
7
+
8
+
9
+ 1. 本文件夹中模仿`talib`,实现同名函数的`polars`版
10
+ 2. 由于减少了python与c来回调用,理论上比直接调用`talib`快
11
+ 3. 优先从`ta`中导入,然后从`wq`中导入,没有的才实现
12
+ 4. 出现循环依赖时,使用`polars`
@@ -0,0 +1,12 @@
1
+ # polars_ta.talib
2
+
3
+ Inside this package, files are generated by `tools.codegen_talib2`.
4
+ It is a wrapper of `talib` functions, with the following features:
5
+
6
+ 1. Input and output are `Expr` instead of `Series`
7
+ 2. ~~Add skipna feature (not efficient, will update when `polars` support backward fill)~~
8
+
9
+ 本包由`tools.codegen_talib2`自动生成,是对`talib`代码的封装。实现了以下功能
10
+ 1. 输入输出由`Series`改`Expr`
11
+ 2. ~~添加跳过空值功能(效率不高,等`polars`支持反向填充,此部分将更新)~~
12
+
@@ -0,0 +1,10 @@
1
+ # polars_ta.tdx
2
+
3
+ 1. Follows the `tdx` naming convention
4
+ 2. Except for some element-wise functions, all functions are time-series functions. Pay special attention to `MAX` and similar functions.
5
+ 3. First import from `tdx`, then from `wq`, and finally from `ta`. Only implement the function if it is not available.
6
+
7
+
8
+ 1. 函数名称按照通达信来
9
+ 2. 除了部分按元素计算的函数,其它都为时序函数,特别注意`MAX`等一类不要混淆
10
+ 3. 优先从`tdx`中导入,然后从`wq`中导入,最后从`ta`,没有的才实现
polars_ta/utils/numba_.py CHANGED
@@ -27,6 +27,7 @@ def isnan(x):
27
27
 
28
28
  @jit(nopython=True, nogil=True, cache=True)
29
29
  def full_with_window_size(arr, fill_value, dtype=None, window_size: int = 1):
30
+ """创建一个更大的数组,填充后一截数据"""
30
31
  out = full(arr.shape[0] + window_size - 1, fill_value, dtype=dtype)
31
32
  out[window_size - 1:] = arr
32
33
  return out
@@ -34,6 +35,7 @@ def full_with_window_size(arr, fill_value, dtype=None, window_size: int = 1):
34
35
 
35
36
  @jit(nopython=True, nogil=True, cache=True)
36
37
  def sliding_window_with_min_periods(arr, window_size: int, min_periods: int):
38
+ """为rolling准备的数据,当数据长度不足时,用nan填充"""
37
39
  windows = sliding_window_view(arr, window_size)
38
40
  valid_counts = np.sum(~np.isnan(windows), axis=1)
39
41
  # 修改这一行,使用布尔索引而不是np.where
@@ -1,10 +1,11 @@
1
1
  import numpy as np
2
- from polars import Expr, Series, fold, any_horizontal, Float64
2
+ from polars import Expr, Series, fold, any_horizontal, Float64, Int64
3
+ from polars import arctan2 as _arctan2
3
4
  from polars import max_horizontal, sum_horizontal, min_horizontal, mean_horizontal
4
5
 
5
6
 
6
7
  def abs_(x: Expr) -> Expr:
7
- """绝对值
8
+ """求绝对值
8
9
 
9
10
  Examples
10
11
  --------
@@ -38,7 +39,7 @@ def abs_(x: Expr) -> Expr:
38
39
 
39
40
 
40
41
  def add(a: Expr, b: Expr, *args) -> Expr:
41
- """水平多列加
42
+ """水平多列相加
42
43
 
43
44
  Examples
44
45
  --------
@@ -92,6 +93,16 @@ def arc_tan(x: Expr) -> Expr:
92
93
  return x.arctan()
93
94
 
94
95
 
96
+ def arc_tan2(y: Expr, x: Expr) -> Expr:
97
+ """反正切二值函数"""
98
+ return _arctan2(y, x)
99
+
100
+
101
+ def cbrt(x: Expr) -> Expr:
102
+ """立方根"""
103
+ return x.cbrt()
104
+
105
+
95
106
  def ceiling(x: Expr) -> Expr:
96
107
  """向上取整"""
97
108
  return x.ceil()
@@ -107,12 +118,61 @@ def cosh(x: Expr) -> Expr:
107
118
  return x.cosh()
108
119
 
109
120
 
110
- def densify(x: Expr) -> Expr:
121
+ def cot(x: Expr) -> Expr:
122
+ """余切"""
123
+ return x.cot()
124
+
125
+
126
+ def cube(x: Expr) -> Expr:
127
+ """立方"""
128
+ return x.pow(3)
129
+
130
+
131
+ def degrees(x: Expr) -> Expr:
132
+ """弧度转角度"""
133
+ return x.degrees()
134
+
135
+
136
+ def _densify(x: Expr) -> Expr:
111
137
  raise
112
138
 
113
139
 
140
+ def div(x: Expr, y: Expr) -> Expr:
141
+ """x除以y的整数部分
142
+
143
+ Examples
144
+ --------
145
+ ```python
146
+ df = pl.DataFrame({
147
+ 'a': [None, -1.5, 0., 1.5, 2.5],
148
+ 'b': [None, -1, 0, 1, 2],
149
+ }).with_columns(
150
+ out1=div(pl.col('a'), 0),
151
+ out2=div(pl.col('a'), 1),
152
+ out3=div(pl.col('a'), pl.col('b')),
153
+ )
154
+ shape: (5, 5)
155
+ ┌──────┬──────┬──────┬──────┬──────┐
156
+ │ a ┆ b ┆ out1 ┆ out2 ┆ out3 │
157
+ │ --- ┆ --- ┆ --- ┆ --- ┆ --- │
158
+ │ f64 ┆ i64 ┆ i64 ┆ i64 ┆ i64 │
159
+ ╞══════╪══════╪══════╪══════╪══════╡
160
+ │ null ┆ null ┆ null ┆ null ┆ null │
161
+ │ -1.5 ┆ -1 ┆ null ┆ -2 ┆ 1 │
162
+ │ 0.0 ┆ 0 ┆ null ┆ 0 ┆ null │
163
+ │ 1.5 ┆ 1 ┆ null ┆ 1 ┆ 1 │
164
+ │ 2.5 ┆ 2 ┆ null ┆ 2 ┆ 1 │
165
+ └──────┴──────┴──────┴──────┴──────┘
166
+ ```
167
+
168
+ """
169
+ return x.floordiv(y).cast(Int64, strict=False)
170
+
171
+
114
172
  def divide(x: Expr, y: Expr) -> Expr:
115
- """x/y
173
+ """除法
174
+
175
+ x/y
116
176
 
117
177
  Examples
118
178
  --------
@@ -173,7 +233,9 @@ def exp(x: Expr) -> Expr:
173
233
 
174
234
 
175
235
  def expm1(x: Expr) -> Expr:
176
- """对数收益率 转 简单收益率 convert log return to simple return
236
+ """对数收益率 转 简单收益率
237
+
238
+ convert log return to simple return
177
239
 
178
240
  Examples
179
241
  --------
@@ -208,6 +270,7 @@ def floor(x: Expr) -> Expr:
208
270
 
209
271
  def fraction(x: Expr) -> Expr:
210
272
  """小数部分
273
+
211
274
  This operator removes the whole number part and returns the remaining fraction part with sign.
212
275
 
213
276
  Examples
@@ -248,7 +311,9 @@ def fraction(x: Expr) -> Expr:
248
311
 
249
312
 
250
313
  def inverse(x: Expr) -> Expr:
251
- """1/x
314
+ """倒数
315
+
316
+ 1/x
252
317
 
253
318
  Examples
254
319
  --------
@@ -277,7 +342,7 @@ def inverse(x: Expr) -> Expr:
277
342
 
278
343
 
279
344
  def log(x: Expr) -> Expr:
280
- """e为底的对数
345
+ """e为底的对数
281
346
 
282
347
  Examples
283
348
  --------
@@ -309,7 +374,7 @@ def log(x: Expr) -> Expr:
309
374
 
310
375
 
311
376
  def log10(x: Expr) -> Expr:
312
- """10为底的对数
377
+ """10为底的对数
313
378
 
314
379
  Examples
315
380
  --------
@@ -338,7 +403,9 @@ def log10(x: Expr) -> Expr:
338
403
 
339
404
 
340
405
  def log1p(x: Expr) -> Expr:
341
- """简单收益率 转 对数收益率 convert simple return to log return
406
+ """简单收益率 转 对数收益率
407
+
408
+ convert simple return to log return
342
409
 
343
410
  log(x+1)
344
411
 
@@ -368,13 +435,44 @@ def log1p(x: Expr) -> Expr:
368
435
  return x.log1p()
369
436
 
370
437
 
438
+ def log2(x: Expr) -> Expr:
439
+ """以2为底的对数
440
+
441
+ Examples
442
+ --------
443
+ ```python
444
+ df = pl.DataFrame({
445
+ 'a': [None, -1, 0, 1, 2],
446
+ }).with_columns(
447
+ out1=log2(pl.col('a')),
448
+ )
449
+ shape: (5, 2)
450
+ ┌──────┬──────┐
451
+ │ a ┆ out1 │
452
+ │ --- ┆ --- │
453
+ │ i64 ┆ f64 │
454
+ ╞══════╪══════╡
455
+ │ null ┆ null │
456
+ │ -1 ┆ NaN │
457
+ │ 0 ┆ -inf │
458
+ │ 1 ┆ 0.0 │
459
+ │ 2 ┆ 1.0 │
460
+ └──────┴──────┘
461
+ ```
462
+
463
+ """
464
+ return x.log(2)
465
+
466
+
371
467
  def max_(a: Expr, b: Expr, *args) -> Expr:
372
- """水平多列最大值 Maximum value of all inputs. At least 2 inputs are required."""
468
+ """水平多列求最大值
469
+
470
+ Maximum value of all inputs. At least 2 inputs are required."""
373
471
  return max_horizontal(a, b, *args)
374
472
 
375
473
 
376
474
  def mean(a: Expr, b: Expr, *args) -> Expr:
377
- """水平多列均值
475
+ """水平多列求均值
378
476
 
379
477
  Examples
380
478
  --------
@@ -405,12 +503,16 @@ def mean(a: Expr, b: Expr, *args) -> Expr:
405
503
 
406
504
 
407
505
  def min_(a: Expr, b: Expr, *args) -> Expr:
408
- """水平多列最小值 Maximum value of all inputs. At least 2 inputs are required."""
506
+ """水平多列求最小值
507
+
508
+ Maximum value of all inputs. At least 2 inputs are required."""
409
509
  return min_horizontal(a, b, *args)
410
510
 
411
511
 
412
512
  def mod(x: Expr, y: Expr) -> Expr:
413
- """x%y
513
+ """求余
514
+
515
+ x%y
414
516
 
415
517
  Examples
416
518
  --------
@@ -441,7 +543,9 @@ def mod(x: Expr, y: Expr) -> Expr:
441
543
 
442
544
 
443
545
  def multiply(a: Expr, b: Expr, *args) -> Expr:
444
- """水平多列乘 Multiply all inputs. At least 2 inputs are required.
546
+ """水平多列相乘
547
+
548
+ Multiply all inputs. At least 2 inputs are required.
445
549
 
446
550
  Examples
447
551
  --------
@@ -482,7 +586,9 @@ def multiply(a: Expr, b: Expr, *args) -> Expr:
482
586
 
483
587
 
484
588
  def power(x: Expr, y: Expr) -> Expr:
485
- """x ** y
589
+ """乘幂
590
+
591
+ x ** y
486
592
 
487
593
  Examples
488
594
  --------
@@ -515,13 +621,20 @@ def power(x: Expr, y: Expr) -> Expr:
515
621
  return x.pow(y.cast(Float64))
516
622
 
517
623
 
624
+ def radians(x: Expr) -> Expr:
625
+ """角度转弧度"""
626
+ return x.radians()
627
+
628
+
518
629
  def reverse(x: Expr) -> Expr:
519
- """-x"""
630
+ """求相反数"""
520
631
  return -x
521
632
 
522
633
 
523
634
  def round_(x: Expr, decimals: int = 0) -> Expr:
524
- """四舍五入 Round input to closest integer.
635
+ """四舍五入
636
+
637
+ Round input to closest integer.
525
638
 
526
639
  Parameters
527
640
  ----------
@@ -561,7 +674,9 @@ def round_(x: Expr, decimals: int = 0) -> Expr:
561
674
 
562
675
 
563
676
  def round_down(x: Expr, f: int = 1) -> Expr:
564
- """小于输入的f的最大倍数 Round input to greatest multiple of f less than input
677
+ """小于输入的f的最大倍数
678
+
679
+ Round input to greatest multiple of f less than input
565
680
 
566
681
  Parameters
567
682
  ----------
@@ -601,6 +716,8 @@ def round_down(x: Expr, f: int = 1) -> Expr:
601
716
  def s_log_1p(x: Expr) -> Expr:
602
717
  """sign(x) * log10(1 + abs(x))
603
718
 
719
+ 一种结合符号函数和对数变换的复合函数,常用于‌保留数据符号的同时压缩数值范围‌
720
+
604
721
  Examples
605
722
  --------
606
723
  ```python
@@ -637,7 +754,7 @@ def s_log_1p(x: Expr) -> Expr:
637
754
 
638
755
 
639
756
  def sign(x: Expr) -> Expr:
640
- """符号"""
757
+ """符号函数"""
641
758
  if isinstance(x, (Expr, Series)):
642
759
  return x.sign()
643
760
  else:
@@ -645,7 +762,9 @@ def sign(x: Expr) -> Expr:
645
762
 
646
763
 
647
764
  def signed_power(x: Expr, y: Expr) -> Expr:
648
- """x raised to the power of y such that final result preserves sign of x.
765
+ """xy次幂,符号保留
766
+
767
+ x raised to the power of y such that final result preserves sign of x.
649
768
 
650
769
  Examples
651
770
  --------
@@ -701,7 +820,7 @@ def sinh(x: Expr) -> Expr:
701
820
 
702
821
 
703
822
  def softsign(x: Expr) -> Expr:
704
- """softsign是 tanh激活函数的另一个替代选择
823
+ """softsign激活函数
705
824
 
706
825
  Examples
707
826
  --------
@@ -735,8 +854,15 @@ def sqrt(x: Expr) -> Expr:
735
854
  return x.sqrt()
736
855
 
737
856
 
857
+ def square(x: Expr) -> Expr:
858
+ """平方"""
859
+ return x.pow(2)
860
+
861
+
738
862
  def subtract(x: Expr, y: Expr) -> Expr:
739
- """x-y"""
863
+ """减法
864
+
865
+ x-y"""
740
866
  return x - y
741
867
 
742
868
 
@@ -801,7 +927,7 @@ def tanh(x: Expr) -> Expr:
801
927
 
802
928
 
803
929
  def var(a: Expr, b: Expr, *args) -> Expr:
804
- """水平多列方差
930
+ """水平多列求方差
805
931
 
806
932
  Examples
807
933
  --------
@@ -835,7 +961,7 @@ def var(a: Expr, b: Expr, *args) -> Expr:
835
961
 
836
962
 
837
963
  def std(a: Expr, b: Expr, *args) -> Expr:
838
- """水平多列标准差
964
+ """水平多列求标准差
839
965
 
840
966
  Examples
841
967
  --------