expr-codegen 0.6.1__tar.gz → 0.6.3__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.
Files changed (28) hide show
  1. {expr_codegen-0.6.1 → expr_codegen-0.6.3}/PKG-INFO +1 -1
  2. expr_codegen-0.6.3/expr_codegen/_version.py +1 -0
  3. {expr_codegen-0.6.1 → expr_codegen-0.6.3}/expr_codegen/codes.py +23 -8
  4. {expr_codegen-0.6.1 → expr_codegen-0.6.3}/expr_codegen/pandas/template.py.j2 +2 -1
  5. {expr_codegen-0.6.1 → expr_codegen-0.6.3}/expr_codegen/polars/template.py.j2 +2 -1
  6. {expr_codegen-0.6.1 → expr_codegen-0.6.3}/expr_codegen/tool.py +56 -1
  7. {expr_codegen-0.6.1 → expr_codegen-0.6.3}/expr_codegen.egg-info/PKG-INFO +1 -1
  8. expr_codegen-0.6.1/expr_codegen/_version.py +0 -1
  9. {expr_codegen-0.6.1 → expr_codegen-0.6.3}/LICENSE +0 -0
  10. {expr_codegen-0.6.1 → expr_codegen-0.6.3}/README.md +0 -0
  11. {expr_codegen-0.6.1 → expr_codegen-0.6.3}/expr_codegen/__init__.py +0 -0
  12. {expr_codegen-0.6.1 → expr_codegen-0.6.3}/expr_codegen/dag.py +0 -0
  13. {expr_codegen-0.6.1 → expr_codegen-0.6.3}/expr_codegen/expr.py +0 -0
  14. {expr_codegen-0.6.1 → expr_codegen-0.6.3}/expr_codegen/latex/__init__.py +0 -0
  15. {expr_codegen-0.6.1 → expr_codegen-0.6.3}/expr_codegen/latex/printer.py +0 -0
  16. {expr_codegen-0.6.1 → expr_codegen-0.6.3}/expr_codegen/model.py +0 -0
  17. {expr_codegen-0.6.1 → expr_codegen-0.6.3}/expr_codegen/pandas/__init__.py +0 -0
  18. {expr_codegen-0.6.1 → expr_codegen-0.6.3}/expr_codegen/pandas/code.py +0 -0
  19. {expr_codegen-0.6.1 → expr_codegen-0.6.3}/expr_codegen/pandas/printer.py +0 -0
  20. {expr_codegen-0.6.1 → expr_codegen-0.6.3}/expr_codegen/polars/__init__.py +0 -0
  21. {expr_codegen-0.6.1 → expr_codegen-0.6.3}/expr_codegen/polars/code.py +0 -0
  22. {expr_codegen-0.6.1 → expr_codegen-0.6.3}/expr_codegen/polars/printer.py +0 -0
  23. {expr_codegen-0.6.1 → expr_codegen-0.6.3}/expr_codegen.egg-info/SOURCES.txt +0 -0
  24. {expr_codegen-0.6.1 → expr_codegen-0.6.3}/expr_codegen.egg-info/dependency_links.txt +0 -0
  25. {expr_codegen-0.6.1 → expr_codegen-0.6.3}/expr_codegen.egg-info/requires.txt +0 -0
  26. {expr_codegen-0.6.1 → expr_codegen-0.6.3}/expr_codegen.egg-info/top_level.txt +0 -0
  27. {expr_codegen-0.6.1 → expr_codegen-0.6.3}/pyproject.toml +0 -0
  28. {expr_codegen-0.6.1 → expr_codegen-0.6.3}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: expr_codegen
3
- Version: 0.6.1
3
+ Version: 0.6.3
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
@@ -0,0 +1 @@
1
+ __version__ = "0.6.3"
@@ -1,5 +1,6 @@
1
1
  import ast
2
2
  import re
3
+ from ast import expr
3
4
 
4
5
  from sympy import Add, Mul, Pow, Eq
5
6
 
@@ -21,7 +22,7 @@ class SympyTransformer(ast.NodeTransformer):
21
22
  # 映射
22
23
  funcs_map = {}
23
24
  args_map = {}
24
- targets_map = {}
25
+ targets_map = {} # 只对非下划线开头的生效
25
26
 
26
27
  def config_map(self, funcs_map, args_map, targets_map):
27
28
  self.funcs_map = funcs_map
@@ -43,18 +44,33 @@ class SympyTransformer(ast.NodeTransformer):
43
44
  self.generic_visit(node)
44
45
  return node
45
46
 
47
+ def __visit_Assign(self, target: expr):
48
+ old_target_id = target.id
49
+ new_target_id = self.targets_map.get(old_target_id, old_target_id)
50
+ self.targets_old.add(old_target_id)
51
+
52
+ # 赋值给下划线开头代码时,对其进行重命名,方便重复书写表达式时不冲突
53
+ if old_target_id.startswith('_'):
54
+ new_target_id = f'{old_target_id}_{len(self.targets_new):03d}'
55
+
56
+ if old_target_id != new_target_id:
57
+ self.targets_new.add(new_target_id)
58
+ target.id = new_target_id
59
+ # 记录修改的变量名,之后会使用到
60
+ self.args_map[old_target_id] = new_target_id
61
+
46
62
  def visit_Assign(self, node):
63
+ # 调整位置,支持循环赋值
64
+ # _A = _A+1 调整成 _A_001 = _A_000 + 1
65
+ self.generic_visit(node)
66
+
47
67
  # 提取输出变量名
48
68
  for target in node.targets:
49
69
  if isinstance(target, ast.Tuple):
50
70
  for t in target.elts:
51
- self.targets_old.add(t.id)
52
- t.id = self.targets_map.get(t.id, t.id)
53
- self.targets_new.add(t.id)
71
+ self.__visit_Assign(t)
54
72
  else:
55
- self.targets_old.add(target.id)
56
- target.id = self.targets_map.get(target.id, target.id)
57
- self.targets_new.add(target.id)
73
+ self.__visit_Assign(target)
58
74
 
59
75
  # 处理 alpha=close 这种情况
60
76
  if isinstance(node.value, ast.Name):
@@ -62,7 +78,6 @@ class SympyTransformer(ast.NodeTransformer):
62
78
  node.value.id = self.args_map.get(node.value.id, node.value.id)
63
79
  self.args_new.add(node.value.id)
64
80
 
65
- self.generic_visit(node)
66
81
  return node
67
82
 
68
83
  def visit_Compare(self, node):
@@ -56,7 +56,8 @@ def main(df: pd.DataFrame) -> pd.DataFrame:
56
56
  {% endfor %}
57
57
 
58
58
  # drop intermediate columns
59
- df = df.drop(columns=list(filter(lambda x: re.search(r"^_x_\d+", x), df.columns)))
59
+ # df = df.drop(columns=list(filter(lambda x: re.search(r"^_x_\d+", x), df.columns)))
60
+ df = df.drop(columns=list(filter(lambda x: x.startswith("_"), df.columns)))
60
61
 
61
62
  # logger.info('done')
62
63
 
@@ -58,7 +58,8 @@ def main(df: pl.DataFrame) -> pl.DataFrame:
58
58
  {% endfor %}
59
59
 
60
60
  # drop intermediate columns
61
- df = df.select(pl.exclude(r'^_x_\d+$'))
61
+ # df = df.select(pl.exclude(r'^_x_\d+$'))
62
+ df = df.select(~cs.starts_with("_"))
62
63
 
63
64
  # shrink
64
65
  df = df.select(cs.all().shrink_dtype())
@@ -1,9 +1,11 @@
1
1
  import inspect
2
- from typing import Sequence, Dict
2
+ from functools import lru_cache
3
+ from typing import Sequence, Dict, Optional
3
4
 
4
5
  from black import Mode, format_str
5
6
  from sympy import simplify, cse, symbols, numbered_symbols
6
7
 
8
+ from expr_codegen.codes import sources_to_exprs
7
9
  from expr_codegen.expr import get_current_by_prefix, get_children, replace_exprs
8
10
  from expr_codegen.model import dag_start, dag_end, dag_middle
9
11
 
@@ -15,6 +17,7 @@ class ExprTool:
15
17
  self.get_current_func_kwargs = {}
16
18
  self.exprs_dict = {}
17
19
  self.exprs_names = []
20
+ self.globals_ = {}
18
21
 
19
22
  def set_current(self, func, **kwargs):
20
23
  self.get_current_func = func
@@ -206,3 +209,55 @@ class ExprTool:
206
209
  codes = format_str(codes, mode=Mode(line_length=600, magic_trailing_comma=True))
207
210
 
208
211
  return codes, G
212
+
213
+ def exec(self, codes: str, df_input):
214
+ """执行代码
215
+
216
+ Notes
217
+ -----
218
+ 注意生成的代码已经约定输入用df_input,输出用df_output
219
+
220
+ """
221
+ globals_ = {'df_input': df_input}
222
+ exec(codes, globals_)
223
+ return globals_['df_output']
224
+
225
+ @lru_cache(maxsize=64)
226
+ def _get_codes(self, source: str, extra_codes: str, output_file: str) -> str:
227
+ """通过字符串生成代码, 加了缓存,多次调用不重复生成"""
228
+ raw, exprs_dict = sources_to_exprs(self.globals_, source, safe=False)
229
+
230
+ # 生成代码
231
+ codes, G = _TOOL_.all(exprs_dict, style='polars', template_file='template.py.j2',
232
+ replace=True, regroup=True, format=True,
233
+ date='date', asset='asset',
234
+ # 复制了需要使用的函数,还复制了最原始的表达式
235
+ extra_codes=(raw,
236
+ # 传入多个列的方法
237
+ extra_codes,
238
+ ))
239
+
240
+ if output_file is not None:
241
+ with open(output_file, 'w', encoding='utf-8') as f:
242
+ f.write(codes)
243
+
244
+ return codes
245
+
246
+
247
+ _TOOL_ = ExprTool()
248
+
249
+
250
+ def codegen_exec(globals_, code_block, df_input,
251
+ extra_codes: str = r'CS_SW_L1 = pl.col(r"^sw_l1_\d+$")',
252
+ output_file: Optional[str] = None):
253
+ """快速转换源代码并执行"""
254
+ _TOOL_.globals_ = globals_
255
+
256
+ if isinstance(code_block, str):
257
+ source = code_block
258
+ else:
259
+ source = inspect.getsource(code_block)
260
+
261
+ codes = _TOOL_._get_codes(source, extra_codes, output_file)
262
+
263
+ return _TOOL_.exec(codes, df_input)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: expr_codegen
3
- Version: 0.6.1
3
+ Version: 0.6.3
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
@@ -1 +0,0 @@
1
- __version__ = "0.6.1"
File without changes
File without changes
File without changes