expr-codegen 0.10.6__tar.gz → 0.10.7__tar.gz
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.
- {expr_codegen-0.10.6 → expr_codegen-0.10.7}/PKG-INFO +22 -23
- {expr_codegen-0.10.6 → expr_codegen-0.10.7}/README.md +21 -22
- expr_codegen-0.10.7/expr_codegen/_version.py +1 -0
- {expr_codegen-0.10.6 → expr_codegen-0.10.7}/expr_codegen/tool.py +7 -7
- {expr_codegen-0.10.6 → expr_codegen-0.10.7}/expr_codegen.egg-info/PKG-INFO +22 -23
- expr_codegen-0.10.6/expr_codegen/_version.py +0 -1
- {expr_codegen-0.10.6 → expr_codegen-0.10.7}/LICENSE +0 -0
- {expr_codegen-0.10.6 → expr_codegen-0.10.7}/expr_codegen/__init__.py +0 -0
- {expr_codegen-0.10.6 → expr_codegen-0.10.7}/expr_codegen/codes.py +0 -0
- {expr_codegen-0.10.6 → expr_codegen-0.10.7}/expr_codegen/dag.py +0 -0
- {expr_codegen-0.10.6 → expr_codegen-0.10.7}/expr_codegen/expr.py +0 -0
- {expr_codegen-0.10.6 → expr_codegen-0.10.7}/expr_codegen/latex/__init__.py +0 -0
- {expr_codegen-0.10.6 → expr_codegen-0.10.7}/expr_codegen/latex/printer.py +0 -0
- {expr_codegen-0.10.6 → expr_codegen-0.10.7}/expr_codegen/model.py +0 -0
- {expr_codegen-0.10.6 → expr_codegen-0.10.7}/expr_codegen/pandas/__init__.py +0 -0
- {expr_codegen-0.10.6 → expr_codegen-0.10.7}/expr_codegen/pandas/code.py +0 -0
- {expr_codegen-0.10.6 → expr_codegen-0.10.7}/expr_codegen/pandas/helper.py +0 -0
- {expr_codegen-0.10.6 → expr_codegen-0.10.7}/expr_codegen/pandas/printer.py +0 -0
- {expr_codegen-0.10.6 → expr_codegen-0.10.7}/expr_codegen/pandas/ta.py +0 -0
- {expr_codegen-0.10.6 → expr_codegen-0.10.7}/expr_codegen/pandas/template.py.j2 +0 -0
- {expr_codegen-0.10.6 → expr_codegen-0.10.7}/expr_codegen/polars_group/__init__.py +0 -0
- {expr_codegen-0.10.6 → expr_codegen-0.10.7}/expr_codegen/polars_group/code.py +0 -0
- {expr_codegen-0.10.6 → expr_codegen-0.10.7}/expr_codegen/polars_group/printer.py +0 -0
- {expr_codegen-0.10.6 → expr_codegen-0.10.7}/expr_codegen/polars_group/template.py.j2 +0 -0
- {expr_codegen-0.10.6 → expr_codegen-0.10.7}/expr_codegen/polars_over/__init__.py +0 -0
- {expr_codegen-0.10.6 → expr_codegen-0.10.7}/expr_codegen/polars_over/code.py +0 -0
- {expr_codegen-0.10.6 → expr_codegen-0.10.7}/expr_codegen/polars_over/printer.py +0 -0
- {expr_codegen-0.10.6 → expr_codegen-0.10.7}/expr_codegen/polars_over/template.py.j2 +0 -0
- {expr_codegen-0.10.6 → expr_codegen-0.10.7}/expr_codegen.egg-info/SOURCES.txt +0 -0
- {expr_codegen-0.10.6 → expr_codegen-0.10.7}/expr_codegen.egg-info/dependency_links.txt +0 -0
- {expr_codegen-0.10.6 → expr_codegen-0.10.7}/expr_codegen.egg-info/requires.txt +0 -0
- {expr_codegen-0.10.6 → expr_codegen-0.10.7}/expr_codegen.egg-info/top_level.txt +0 -0
- {expr_codegen-0.10.6 → expr_codegen-0.10.7}/pyproject.toml +0 -0
- {expr_codegen-0.10.6 → expr_codegen-0.10.7}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: expr_codegen
|
|
3
|
-
Version: 0.10.
|
|
3
|
+
Version: 0.10.7
|
|
4
4
|
Summary: symbol expression to polars expression tool
|
|
5
5
|
Author-email: wukan <wu-kan@163.com>
|
|
6
6
|
License: BSD 3-Clause License
|
|
@@ -48,9 +48,7 @@ Requires-Dist: streamlit; extra == "streamlit"
|
|
|
48
48
|
Requires-Dist: streamlit-ace; extra == "streamlit"
|
|
49
49
|
Requires-Dist: more_itertools; extra == "streamlit"
|
|
50
50
|
|
|
51
|
-
# expr_codegen
|
|
52
|
-
|
|
53
|
-
表达式转代码工具
|
|
51
|
+
# expr_codegen 表达式转译器
|
|
54
52
|
|
|
55
53
|
## 项目背景
|
|
56
54
|
|
|
@@ -79,14 +77,9 @@ https://exprcodegen.streamlit.app
|
|
|
79
77
|
|
|
80
78
|
```python
|
|
81
79
|
import sys
|
|
80
|
+
from io import StringIO
|
|
82
81
|
|
|
83
|
-
|
|
84
|
-
from polars_ta.prefix.cdl import * # noqa
|
|
85
|
-
from polars_ta.prefix.ta import * # noqa
|
|
86
|
-
from polars_ta.prefix.tdx import * # noqa
|
|
87
|
-
from polars_ta.prefix.wq import * # noqa
|
|
88
|
-
|
|
89
|
-
from expr_codegen.tool import codegen_exec
|
|
82
|
+
from expr_codegen import codegen_exec
|
|
90
83
|
|
|
91
84
|
|
|
92
85
|
def _code_block_1():
|
|
@@ -114,10 +107,15 @@ def _code_block_2():
|
|
|
114
107
|
CPV = cs_zscore(_corr) + cs_zscore(_beta)
|
|
115
108
|
|
|
116
109
|
|
|
110
|
+
code = StringIO()
|
|
111
|
+
|
|
117
112
|
df = None # 替换成真实的polars数据
|
|
118
113
|
df = codegen_exec(df, _code_block_1, _code_block_2, output_file=sys.stdout) # 打印代码
|
|
119
114
|
df = codegen_exec(df, _code_block_1, _code_block_2, output_file="output.py") # 保存到文件
|
|
120
115
|
df = codegen_exec(df, _code_block_1, _code_block_2) # 只执行,不保存代码
|
|
116
|
+
df = codegen_exec(df, _code_block_1, _code_block_2, output_file=code) # 保存到字符串
|
|
117
|
+
code.seek(0)
|
|
118
|
+
code.read() # 读取代码
|
|
121
119
|
|
|
122
120
|
df = codegen_exec(df.lazy(), _code_block_1, _code_block_2).collect() # Lazy CPU
|
|
123
121
|
df = codegen_exec(df.lazy(), _code_block_1, _code_block_2).collect(engine="gpu") # Lazy GPU
|
|
@@ -138,7 +136,7 @@ df = codegen_exec(df.lazy(), _code_block_1, _code_block_2).collect(engine="gpu")
|
|
|
138
136
|
│ sympy_define.py # 符号定义,由于太多地方重复使用到,所以统一提取到此处
|
|
139
137
|
├─expr_codegen
|
|
140
138
|
│ │ expr.py # 表达式处理基本函数
|
|
141
|
-
│ │ tool.py #
|
|
139
|
+
│ │ tool.py # 核心工具代码
|
|
142
140
|
│ ├─polars
|
|
143
141
|
│ │ │ code.py # 针对polars语法的代码生成功能
|
|
144
142
|
│ │ │ template.py.j2 # `Jinja2`模板。用于生成对应py文件,一般不需修改
|
|
@@ -185,13 +183,20 @@ df = codegen_exec(df.lazy(), _code_block_1, _code_block_2).collect(engine="gpu")
|
|
|
185
183
|
1. 根据算子前缀分类(`get_current_by_prefix`),限制算子必需以`ts_`、`cs_`、`gp_`开头
|
|
186
184
|
2. 根据算子全名分类(`get_current_by_name`), 不再限制算子名。比如`cs_rank`可以叫`rank`
|
|
187
185
|
|
|
188
|
-
## Null
|
|
186
|
+
## Null处理
|
|
187
|
+
|
|
188
|
+
`null`是如何产生的?
|
|
189
|
+
|
|
190
|
+
1. 停牌导致。在计算前就直接过滤掉了,不会对后续计算产生影响。
|
|
191
|
+
2. 不同品种交易时段不同
|
|
192
|
+
3. 计算产生。`null`在数列两端不影响后续时序算子结果,但中间出现`null`会影响。例如: `if_else(close<2, None, close)`
|
|
189
193
|
|
|
190
194
|
https://github.com/pola-rs/polars/issues/12925#issuecomment-2552764629
|
|
195
|
+
|
|
191
196
|
非常棒的点子,总结下来有两种实现方式:
|
|
192
197
|
|
|
193
|
-
1. 将`null`分成一组,`not_null
|
|
194
|
-
2. 仅一组,但复合排序,将`null`排在前面,`not_null
|
|
198
|
+
1. 将`null`分成一组,`not_null`分成另一组。要调用两次
|
|
199
|
+
2. 仅一组,但复合排序,将`null`排在前面,`not_null`排后面。只调用一次,略快一些
|
|
195
200
|
|
|
196
201
|
```python
|
|
197
202
|
X1 = (ts_returns(CLOSE, 3)).over(CLOSE.is_not_null(), _ASSET_, order_by=_DATE_),
|
|
@@ -199,17 +204,11 @@ X2 = (ts_returns(CLOSE, 3)).over(_ASSET_, order_by=[CLOSE.is_not_null(), _DATE_]
|
|
|
199
204
|
X3 = (ts_returns(CLOSE, 3)).over(_ASSET_, order_by=_DATE_),
|
|
200
205
|
```
|
|
201
206
|
|
|
202
|
-
第2种开头的`null
|
|
207
|
+
第2种开头的`null`区域,是否影响结果由算子所决定,特别时是多列输入时`null`区域可能有数据
|
|
203
208
|
|
|
204
209
|
1. `over_null='partition_by'`。分到两个区域
|
|
205
210
|
2. `over_null='order_by'`。分到一个区域,`null`排在前面
|
|
206
|
-
3. `over_null=None
|
|
207
|
-
|
|
208
|
-
## 二次开发
|
|
209
|
-
|
|
210
|
-
1. 备份后编辑`demo_express.py`, `import`需要引入的函数
|
|
211
|
-
2. 然后`printer.py`有可能需要添加对应函数的打印代码
|
|
212
|
-
- 注意:需要留意是否要加括号`()`,不加时可能优先级混乱,可以每次都加括号,也可用提供的`parenthesize`简化处理
|
|
211
|
+
3. `over_null=None`。不处理,直接调用,速度更快。如果确信不会中段产生`null`建议使用此参数
|
|
213
212
|
|
|
214
213
|
## `expr_codegen`局限性
|
|
215
214
|
|
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
# expr_codegen
|
|
2
|
-
|
|
3
|
-
表达式转代码工具
|
|
1
|
+
# expr_codegen 表达式转译器
|
|
4
2
|
|
|
5
3
|
## 项目背景
|
|
6
4
|
|
|
@@ -29,14 +27,9 @@ https://exprcodegen.streamlit.app
|
|
|
29
27
|
|
|
30
28
|
```python
|
|
31
29
|
import sys
|
|
30
|
+
from io import StringIO
|
|
32
31
|
|
|
33
|
-
|
|
34
|
-
from polars_ta.prefix.cdl import * # noqa
|
|
35
|
-
from polars_ta.prefix.ta import * # noqa
|
|
36
|
-
from polars_ta.prefix.tdx import * # noqa
|
|
37
|
-
from polars_ta.prefix.wq import * # noqa
|
|
38
|
-
|
|
39
|
-
from expr_codegen.tool import codegen_exec
|
|
32
|
+
from expr_codegen import codegen_exec
|
|
40
33
|
|
|
41
34
|
|
|
42
35
|
def _code_block_1():
|
|
@@ -64,10 +57,15 @@ def _code_block_2():
|
|
|
64
57
|
CPV = cs_zscore(_corr) + cs_zscore(_beta)
|
|
65
58
|
|
|
66
59
|
|
|
60
|
+
code = StringIO()
|
|
61
|
+
|
|
67
62
|
df = None # 替换成真实的polars数据
|
|
68
63
|
df = codegen_exec(df, _code_block_1, _code_block_2, output_file=sys.stdout) # 打印代码
|
|
69
64
|
df = codegen_exec(df, _code_block_1, _code_block_2, output_file="output.py") # 保存到文件
|
|
70
65
|
df = codegen_exec(df, _code_block_1, _code_block_2) # 只执行,不保存代码
|
|
66
|
+
df = codegen_exec(df, _code_block_1, _code_block_2, output_file=code) # 保存到字符串
|
|
67
|
+
code.seek(0)
|
|
68
|
+
code.read() # 读取代码
|
|
71
69
|
|
|
72
70
|
df = codegen_exec(df.lazy(), _code_block_1, _code_block_2).collect() # Lazy CPU
|
|
73
71
|
df = codegen_exec(df.lazy(), _code_block_1, _code_block_2).collect(engine="gpu") # Lazy GPU
|
|
@@ -88,7 +86,7 @@ df = codegen_exec(df.lazy(), _code_block_1, _code_block_2).collect(engine="gpu")
|
|
|
88
86
|
│ sympy_define.py # 符号定义,由于太多地方重复使用到,所以统一提取到此处
|
|
89
87
|
├─expr_codegen
|
|
90
88
|
│ │ expr.py # 表达式处理基本函数
|
|
91
|
-
│ │ tool.py #
|
|
89
|
+
│ │ tool.py # 核心工具代码
|
|
92
90
|
│ ├─polars
|
|
93
91
|
│ │ │ code.py # 针对polars语法的代码生成功能
|
|
94
92
|
│ │ │ template.py.j2 # `Jinja2`模板。用于生成对应py文件,一般不需修改
|
|
@@ -135,13 +133,20 @@ df = codegen_exec(df.lazy(), _code_block_1, _code_block_2).collect(engine="gpu")
|
|
|
135
133
|
1. 根据算子前缀分类(`get_current_by_prefix`),限制算子必需以`ts_`、`cs_`、`gp_`开头
|
|
136
134
|
2. 根据算子全名分类(`get_current_by_name`), 不再限制算子名。比如`cs_rank`可以叫`rank`
|
|
137
135
|
|
|
138
|
-
## Null
|
|
136
|
+
## Null处理
|
|
137
|
+
|
|
138
|
+
`null`是如何产生的?
|
|
139
|
+
|
|
140
|
+
1. 停牌导致。在计算前就直接过滤掉了,不会对后续计算产生影响。
|
|
141
|
+
2. 不同品种交易时段不同
|
|
142
|
+
3. 计算产生。`null`在数列两端不影响后续时序算子结果,但中间出现`null`会影响。例如: `if_else(close<2, None, close)`
|
|
139
143
|
|
|
140
144
|
https://github.com/pola-rs/polars/issues/12925#issuecomment-2552764629
|
|
145
|
+
|
|
141
146
|
非常棒的点子,总结下来有两种实现方式:
|
|
142
147
|
|
|
143
|
-
1. 将`null`分成一组,`not_null
|
|
144
|
-
2. 仅一组,但复合排序,将`null`排在前面,`not_null
|
|
148
|
+
1. 将`null`分成一组,`not_null`分成另一组。要调用两次
|
|
149
|
+
2. 仅一组,但复合排序,将`null`排在前面,`not_null`排后面。只调用一次,略快一些
|
|
145
150
|
|
|
146
151
|
```python
|
|
147
152
|
X1 = (ts_returns(CLOSE, 3)).over(CLOSE.is_not_null(), _ASSET_, order_by=_DATE_),
|
|
@@ -149,17 +154,11 @@ X2 = (ts_returns(CLOSE, 3)).over(_ASSET_, order_by=[CLOSE.is_not_null(), _DATE_]
|
|
|
149
154
|
X3 = (ts_returns(CLOSE, 3)).over(_ASSET_, order_by=_DATE_),
|
|
150
155
|
```
|
|
151
156
|
|
|
152
|
-
第2种开头的`null
|
|
157
|
+
第2种开头的`null`区域,是否影响结果由算子所决定,特别时是多列输入时`null`区域可能有数据
|
|
153
158
|
|
|
154
159
|
1. `over_null='partition_by'`。分到两个区域
|
|
155
160
|
2. `over_null='order_by'`。分到一个区域,`null`排在前面
|
|
156
|
-
3. `over_null=None
|
|
157
|
-
|
|
158
|
-
## 二次开发
|
|
159
|
-
|
|
160
|
-
1. 备份后编辑`demo_express.py`, `import`需要引入的函数
|
|
161
|
-
2. 然后`printer.py`有可能需要添加对应函数的打印代码
|
|
162
|
-
- 注意:需要留意是否要加括号`()`,不加时可能优先级混乱,可以每次都加括号,也可用提供的`parenthesize`简化处理
|
|
161
|
+
3. `over_null=None`。不处理,直接调用,速度更快。如果确信不会中段产生`null`建议使用此参数
|
|
163
162
|
|
|
164
163
|
## `expr_codegen`局限性
|
|
165
164
|
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.10.7"
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import inspect
|
|
2
2
|
import pathlib
|
|
3
3
|
from functools import lru_cache
|
|
4
|
-
from io import
|
|
5
|
-
from typing import Sequence, Dict, Union,
|
|
4
|
+
from io import TextIOBase
|
|
5
|
+
from typing import Sequence, Dict, Union, TypeVar, Optional, Literal
|
|
6
6
|
|
|
7
7
|
from black import Mode, format_str
|
|
8
8
|
from loguru import logger
|
|
@@ -286,7 +286,7 @@ class ExprTool:
|
|
|
286
286
|
**kwargs)
|
|
287
287
|
|
|
288
288
|
# 移回到cache,防止多次调用多次保存
|
|
289
|
-
if isinstance(output_file,
|
|
289
|
+
if isinstance(output_file, TextIOBase):
|
|
290
290
|
# 输出到控制台
|
|
291
291
|
output_file.write(code)
|
|
292
292
|
elif output_file is not None:
|
|
@@ -322,13 +322,13 @@ _TOOL_ = ExprTool()
|
|
|
322
322
|
def codegen_exec(df: Optional[DataFrame],
|
|
323
323
|
*codes,
|
|
324
324
|
extra_codes: str = r'CS_SW_L1 = r"^sw_l1_\d+$"',
|
|
325
|
-
output_file: Union[str,
|
|
325
|
+
output_file: Union[str, TextIOBase, None] = None,
|
|
326
326
|
run_file: Union[bool, str] = False,
|
|
327
327
|
convert_xor: bool = False,
|
|
328
328
|
style: Literal['pandas', 'polars_group', 'polars_over'] = 'polars_over',
|
|
329
329
|
template_file: str = 'template.py.j2',
|
|
330
330
|
date: str = 'date', asset: str = 'asset',
|
|
331
|
-
over_null: Literal['
|
|
331
|
+
over_null: Literal['partition_by', 'order_by', None] = 'partition_by',
|
|
332
332
|
**kwargs) -> Optional[DataFrame]:
|
|
333
333
|
"""快速转换源代码并执行
|
|
334
334
|
|
|
@@ -340,7 +340,7 @@ def codegen_exec(df: Optional[DataFrame],
|
|
|
340
340
|
函数体。此部分中的表达式会被翻译成目标代码
|
|
341
341
|
extra_codes: str
|
|
342
342
|
额外代码。不做处理,会被直接复制到目标代码中
|
|
343
|
-
output_file: str
|
|
343
|
+
output_file: str| TextIOBase
|
|
344
344
|
保存生成的目标代码到文件中
|
|
345
345
|
run_file: bool or str
|
|
346
346
|
是否不生成脚本,直接运行代码。
|
|
@@ -362,8 +362,8 @@ def codegen_exec(df: Optional[DataFrame],
|
|
|
362
362
|
资产字段
|
|
363
363
|
over_null: str
|
|
364
364
|
时序中遇到null时的处理方式
|
|
365
|
-
- order_by: 空值排同一分区的前排
|
|
366
365
|
- partition_by: 空值划分到不同分区
|
|
366
|
+
- order_by: 空值排同一分区的前排
|
|
367
367
|
- None: 不做处理
|
|
368
368
|
|
|
369
369
|
Returns
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: expr_codegen
|
|
3
|
-
Version: 0.10.
|
|
3
|
+
Version: 0.10.7
|
|
4
4
|
Summary: symbol expression to polars expression tool
|
|
5
5
|
Author-email: wukan <wu-kan@163.com>
|
|
6
6
|
License: BSD 3-Clause License
|
|
@@ -48,9 +48,7 @@ Requires-Dist: streamlit; extra == "streamlit"
|
|
|
48
48
|
Requires-Dist: streamlit-ace; extra == "streamlit"
|
|
49
49
|
Requires-Dist: more_itertools; extra == "streamlit"
|
|
50
50
|
|
|
51
|
-
# expr_codegen
|
|
52
|
-
|
|
53
|
-
表达式转代码工具
|
|
51
|
+
# expr_codegen 表达式转译器
|
|
54
52
|
|
|
55
53
|
## 项目背景
|
|
56
54
|
|
|
@@ -79,14 +77,9 @@ https://exprcodegen.streamlit.app
|
|
|
79
77
|
|
|
80
78
|
```python
|
|
81
79
|
import sys
|
|
80
|
+
from io import StringIO
|
|
82
81
|
|
|
83
|
-
|
|
84
|
-
from polars_ta.prefix.cdl import * # noqa
|
|
85
|
-
from polars_ta.prefix.ta import * # noqa
|
|
86
|
-
from polars_ta.prefix.tdx import * # noqa
|
|
87
|
-
from polars_ta.prefix.wq import * # noqa
|
|
88
|
-
|
|
89
|
-
from expr_codegen.tool import codegen_exec
|
|
82
|
+
from expr_codegen import codegen_exec
|
|
90
83
|
|
|
91
84
|
|
|
92
85
|
def _code_block_1():
|
|
@@ -114,10 +107,15 @@ def _code_block_2():
|
|
|
114
107
|
CPV = cs_zscore(_corr) + cs_zscore(_beta)
|
|
115
108
|
|
|
116
109
|
|
|
110
|
+
code = StringIO()
|
|
111
|
+
|
|
117
112
|
df = None # 替换成真实的polars数据
|
|
118
113
|
df = codegen_exec(df, _code_block_1, _code_block_2, output_file=sys.stdout) # 打印代码
|
|
119
114
|
df = codegen_exec(df, _code_block_1, _code_block_2, output_file="output.py") # 保存到文件
|
|
120
115
|
df = codegen_exec(df, _code_block_1, _code_block_2) # 只执行,不保存代码
|
|
116
|
+
df = codegen_exec(df, _code_block_1, _code_block_2, output_file=code) # 保存到字符串
|
|
117
|
+
code.seek(0)
|
|
118
|
+
code.read() # 读取代码
|
|
121
119
|
|
|
122
120
|
df = codegen_exec(df.lazy(), _code_block_1, _code_block_2).collect() # Lazy CPU
|
|
123
121
|
df = codegen_exec(df.lazy(), _code_block_1, _code_block_2).collect(engine="gpu") # Lazy GPU
|
|
@@ -138,7 +136,7 @@ df = codegen_exec(df.lazy(), _code_block_1, _code_block_2).collect(engine="gpu")
|
|
|
138
136
|
│ sympy_define.py # 符号定义,由于太多地方重复使用到,所以统一提取到此处
|
|
139
137
|
├─expr_codegen
|
|
140
138
|
│ │ expr.py # 表达式处理基本函数
|
|
141
|
-
│ │ tool.py #
|
|
139
|
+
│ │ tool.py # 核心工具代码
|
|
142
140
|
│ ├─polars
|
|
143
141
|
│ │ │ code.py # 针对polars语法的代码生成功能
|
|
144
142
|
│ │ │ template.py.j2 # `Jinja2`模板。用于生成对应py文件,一般不需修改
|
|
@@ -185,13 +183,20 @@ df = codegen_exec(df.lazy(), _code_block_1, _code_block_2).collect(engine="gpu")
|
|
|
185
183
|
1. 根据算子前缀分类(`get_current_by_prefix`),限制算子必需以`ts_`、`cs_`、`gp_`开头
|
|
186
184
|
2. 根据算子全名分类(`get_current_by_name`), 不再限制算子名。比如`cs_rank`可以叫`rank`
|
|
187
185
|
|
|
188
|
-
## Null
|
|
186
|
+
## Null处理
|
|
187
|
+
|
|
188
|
+
`null`是如何产生的?
|
|
189
|
+
|
|
190
|
+
1. 停牌导致。在计算前就直接过滤掉了,不会对后续计算产生影响。
|
|
191
|
+
2. 不同品种交易时段不同
|
|
192
|
+
3. 计算产生。`null`在数列两端不影响后续时序算子结果,但中间出现`null`会影响。例如: `if_else(close<2, None, close)`
|
|
189
193
|
|
|
190
194
|
https://github.com/pola-rs/polars/issues/12925#issuecomment-2552764629
|
|
195
|
+
|
|
191
196
|
非常棒的点子,总结下来有两种实现方式:
|
|
192
197
|
|
|
193
|
-
1. 将`null`分成一组,`not_null
|
|
194
|
-
2. 仅一组,但复合排序,将`null`排在前面,`not_null
|
|
198
|
+
1. 将`null`分成一组,`not_null`分成另一组。要调用两次
|
|
199
|
+
2. 仅一组,但复合排序,将`null`排在前面,`not_null`排后面。只调用一次,略快一些
|
|
195
200
|
|
|
196
201
|
```python
|
|
197
202
|
X1 = (ts_returns(CLOSE, 3)).over(CLOSE.is_not_null(), _ASSET_, order_by=_DATE_),
|
|
@@ -199,17 +204,11 @@ X2 = (ts_returns(CLOSE, 3)).over(_ASSET_, order_by=[CLOSE.is_not_null(), _DATE_]
|
|
|
199
204
|
X3 = (ts_returns(CLOSE, 3)).over(_ASSET_, order_by=_DATE_),
|
|
200
205
|
```
|
|
201
206
|
|
|
202
|
-
第2种开头的`null
|
|
207
|
+
第2种开头的`null`区域,是否影响结果由算子所决定,特别时是多列输入时`null`区域可能有数据
|
|
203
208
|
|
|
204
209
|
1. `over_null='partition_by'`。分到两个区域
|
|
205
210
|
2. `over_null='order_by'`。分到一个区域,`null`排在前面
|
|
206
|
-
3. `over_null=None
|
|
207
|
-
|
|
208
|
-
## 二次开发
|
|
209
|
-
|
|
210
|
-
1. 备份后编辑`demo_express.py`, `import`需要引入的函数
|
|
211
|
-
2. 然后`printer.py`有可能需要添加对应函数的打印代码
|
|
212
|
-
- 注意:需要留意是否要加括号`()`,不加时可能优先级混乱,可以每次都加括号,也可用提供的`parenthesize`简化处理
|
|
211
|
+
3. `over_null=None`。不处理,直接调用,速度更快。如果确信不会中段产生`null`建议使用此参数
|
|
213
212
|
|
|
214
213
|
## `expr_codegen`局限性
|
|
215
214
|
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "0.10.6"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|