expr-codegen 0.12.0__tar.gz → 0.12.1__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 (34) hide show
  1. {expr_codegen-0.12.0 → expr_codegen-0.12.1}/PKG-INFO +1 -1
  2. expr_codegen-0.12.1/expr_codegen/_version.py +1 -0
  3. {expr_codegen-0.12.0 → expr_codegen-0.12.1}/expr_codegen/pandas/code.py +5 -6
  4. {expr_codegen-0.12.0 → expr_codegen-0.12.1}/expr_codegen/polars_group/code.py +5 -7
  5. {expr_codegen-0.12.0 → expr_codegen-0.12.1}/expr_codegen/polars_over/code.py +5 -7
  6. {expr_codegen-0.12.0 → expr_codegen-0.12.1}/expr_codegen/tool.py +49 -21
  7. {expr_codegen-0.12.0 → expr_codegen-0.12.1}/expr_codegen.egg-info/PKG-INFO +1 -1
  8. expr_codegen-0.12.0/expr_codegen/_version.py +0 -1
  9. {expr_codegen-0.12.0 → expr_codegen-0.12.1}/LICENSE +0 -0
  10. {expr_codegen-0.12.0 → expr_codegen-0.12.1}/README.md +0 -0
  11. {expr_codegen-0.12.0 → expr_codegen-0.12.1}/expr_codegen/__init__.py +0 -0
  12. {expr_codegen-0.12.0 → expr_codegen-0.12.1}/expr_codegen/codes.py +0 -0
  13. {expr_codegen-0.12.0 → expr_codegen-0.12.1}/expr_codegen/dag.py +0 -0
  14. {expr_codegen-0.12.0 → expr_codegen-0.12.1}/expr_codegen/expr.py +0 -0
  15. {expr_codegen-0.12.0 → expr_codegen-0.12.1}/expr_codegen/latex/__init__.py +0 -0
  16. {expr_codegen-0.12.0 → expr_codegen-0.12.1}/expr_codegen/latex/printer.py +0 -0
  17. {expr_codegen-0.12.0 → expr_codegen-0.12.1}/expr_codegen/model.py +0 -0
  18. {expr_codegen-0.12.0 → expr_codegen-0.12.1}/expr_codegen/pandas/__init__.py +0 -0
  19. {expr_codegen-0.12.0 → expr_codegen-0.12.1}/expr_codegen/pandas/helper.py +0 -0
  20. {expr_codegen-0.12.0 → expr_codegen-0.12.1}/expr_codegen/pandas/printer.py +0 -0
  21. {expr_codegen-0.12.0 → expr_codegen-0.12.1}/expr_codegen/pandas/ta.py +0 -0
  22. {expr_codegen-0.12.0 → expr_codegen-0.12.1}/expr_codegen/pandas/template.py.j2 +0 -0
  23. {expr_codegen-0.12.0 → expr_codegen-0.12.1}/expr_codegen/polars_group/__init__.py +0 -0
  24. {expr_codegen-0.12.0 → expr_codegen-0.12.1}/expr_codegen/polars_group/printer.py +0 -0
  25. {expr_codegen-0.12.0 → expr_codegen-0.12.1}/expr_codegen/polars_group/template.py.j2 +0 -0
  26. {expr_codegen-0.12.0 → expr_codegen-0.12.1}/expr_codegen/polars_over/__init__.py +0 -0
  27. {expr_codegen-0.12.0 → expr_codegen-0.12.1}/expr_codegen/polars_over/printer.py +0 -0
  28. {expr_codegen-0.12.0 → expr_codegen-0.12.1}/expr_codegen/polars_over/template.py.j2 +0 -0
  29. {expr_codegen-0.12.0 → expr_codegen-0.12.1}/expr_codegen.egg-info/SOURCES.txt +0 -0
  30. {expr_codegen-0.12.0 → expr_codegen-0.12.1}/expr_codegen.egg-info/dependency_links.txt +0 -0
  31. {expr_codegen-0.12.0 → expr_codegen-0.12.1}/expr_codegen.egg-info/requires.txt +0 -0
  32. {expr_codegen-0.12.0 → expr_codegen-0.12.1}/expr_codegen.egg-info/top_level.txt +0 -0
  33. {expr_codegen-0.12.0 → expr_codegen-0.12.1}/pyproject.toml +0 -0
  34. {expr_codegen-0.12.0 → expr_codegen-0.12.1}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: expr_codegen
3
- Version: 0.12.0
3
+ Version: 0.12.1
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.12.1"
@@ -1,5 +1,5 @@
1
1
  import os
2
- from typing import Sequence, Dict
2
+ from typing import Sequence
3
3
 
4
4
  import jinja2
5
5
  from jinja2 import FileSystemLoader, TemplateNotFound
@@ -27,9 +27,9 @@ def get_groupby_from_tuple(tup, func_name, drop_cols):
27
27
  return f'df = {func_name}(df).drop(columns={drop_cols})'
28
28
 
29
29
 
30
- def symbols_to_code(syms, alias):
30
+ def symbols_to_code(syms):
31
31
  a = [f"{s}" for s in syms]
32
- b = [f"'{alias.get(s, s)}'" for s in syms]
32
+ b = [f"'{s}'" for s in syms]
33
33
  return f"""_ = [{','.join(b)}]
34
34
  [{','.join(a)}] = _"""
35
35
 
@@ -37,7 +37,6 @@ def symbols_to_code(syms, alias):
37
37
  def codegen(exprs_ldl: ListDictList, exprs_src, syms_dst,
38
38
  filename,
39
39
  date='date', asset='asset',
40
- alias: Dict[str, str] = {},
41
40
  extra_codes: Sequence[str] = (),
42
41
  **kwargs):
43
42
  """基于模板的代码生成"""
@@ -92,8 +91,8 @@ def codegen(exprs_ldl: ListDictList, exprs_src, syms_dst,
92
91
  # 分组应用代码
93
92
  groupbys[func_name] = get_groupby_from_tuple(k, func_name, ds)
94
93
 
95
- syms1 = symbols_to_code(syms_dst, alias)
96
- syms2 = symbols_to_code(syms_out, alias)
94
+ syms1 = symbols_to_code(syms_dst)
95
+ syms2 = symbols_to_code(syms_out)
97
96
 
98
97
  try:
99
98
  env = jinja2.Environment(loader=FileSystemLoader(os.path.dirname(__file__)))
@@ -1,5 +1,5 @@
1
1
  import os
2
- from typing import Sequence, Dict
2
+ from typing import Sequence
3
3
 
4
4
  import jinja2
5
5
  from jinja2 import FileSystemLoader, TemplateNotFound
@@ -27,10 +27,9 @@ def get_groupby_from_tuple(tup, func_name, drop_cols):
27
27
  return f'df = {func_name}(df).drop(*{drop_cols})'
28
28
 
29
29
 
30
- def symbols_to_code(syms, alias):
30
+ def symbols_to_code(syms):
31
31
  a = [f"{s}" for s in syms]
32
- b = [f"r'{alias.get(s, s)}'" for s in syms] #
33
- b = [f"'{alias.get(s, s)}'" for s in syms]
32
+ b = [f"'{s}'" for s in syms]
34
33
  return f"""_ = [{','.join(b)}]
35
34
  [{','.join(a)}] = [pl.col(i) for i in _]"""
36
35
 
@@ -38,7 +37,6 @@ def symbols_to_code(syms, alias):
38
37
  def codegen(exprs_ldl: ListDictList, exprs_src, syms_dst,
39
38
  filename,
40
39
  date='date', asset='asset',
41
- alias: Dict[str, str] = {},
42
40
  extra_codes: Sequence[str] = (),
43
41
  **kwargs):
44
42
  """基于模板的代码生成"""
@@ -100,8 +98,8 @@ def codegen(exprs_ldl: ListDictList, exprs_src, syms_dst,
100
98
  # 分组应用代码
101
99
  groupbys[func_name] = get_groupby_from_tuple(k, func_name, ds)
102
100
 
103
- syms1 = symbols_to_code(syms_dst, alias)
104
- syms2 = symbols_to_code(syms_out, alias)
101
+ syms1 = symbols_to_code(syms_dst)
102
+ syms2 = symbols_to_code(syms_out)
105
103
 
106
104
  try:
107
105
  env = jinja2.Environment(loader=FileSystemLoader(os.path.dirname(__file__)))
@@ -1,6 +1,6 @@
1
1
  import argparse
2
2
  import os
3
- from typing import Sequence, Dict, Literal
3
+ from typing import Sequence, Literal
4
4
 
5
5
  import jinja2
6
6
  from jinja2 import FileSystemLoader, TemplateNotFound
@@ -28,10 +28,9 @@ def get_groupby_from_tuple(tup, func_name, drop_cols):
28
28
  return f'df = {func_name}(df).drop(*{drop_cols})'
29
29
 
30
30
 
31
- def symbols_to_code(syms, alias):
31
+ def symbols_to_code(syms):
32
32
  a = [f"{s}" for s in syms]
33
- b = [f"r'{alias.get(s, s)}'" for s in syms] #
34
- b = [f"'{alias.get(s, s)}'" for s in syms]
33
+ b = [f"'{s}'" for s in syms]
35
34
  return f"""_ = [{','.join(b)}]
36
35
  [{','.join(a)}] = [pl.col(i) for i in _]"""
37
36
 
@@ -39,7 +38,6 @@ def symbols_to_code(syms, alias):
39
38
  def codegen(exprs_ldl: ListDictList, exprs_src, syms_dst,
40
39
  filename,
41
40
  date='date', asset='asset',
42
- alias: Dict[str, str] = {},
43
41
  extra_codes: Sequence[str] = (),
44
42
  over_null: Literal['order_by', 'partition_by', None] = 'partition_by',
45
43
  **kwargs):
@@ -118,8 +116,8 @@ def codegen(exprs_ldl: ListDictList, exprs_src, syms_dst,
118
116
  # 分组应用代码
119
117
  groupbys[func_name] = get_groupby_from_tuple(k, func_name, ds)
120
118
 
121
- syms1 = symbols_to_code(syms_dst, alias)
122
- syms2 = symbols_to_code(syms_out, alias)
119
+ syms1 = symbols_to_code(syms_dst)
120
+ syms2 = symbols_to_code(syms_out)
123
121
 
124
122
  try:
125
123
  env = jinja2.Environment(loader=FileSystemLoader(os.path.dirname(__file__)))
@@ -2,8 +2,9 @@ import inspect
2
2
  import pathlib
3
3
  from functools import lru_cache
4
4
  from io import TextIOBase
5
- from typing import Sequence, Dict, Union, TypeVar, Optional, Literal
5
+ from typing import Sequence, Union, TypeVar, Optional, Literal
6
6
 
7
+ import polars as pl
7
8
  from black import Mode, format_str
8
9
  from loguru import logger
9
10
  from sympy import simplify, cse, symbols, numbered_symbols
@@ -200,8 +201,8 @@ class ExprTool:
200
201
  template_file: Optional[str] = None,
201
202
  replace: bool = True, regroup: bool = False, format: bool = True,
202
203
  date='date', asset='asset',
203
- alias: Dict[str, str] = {},
204
204
  extra_codes: Sequence[object] = (),
205
+ table_name: str = 'self',
205
206
  **kwargs):
206
207
  """功能集成版,将几个功能写到一起方便使用
207
208
 
@@ -223,8 +224,6 @@ class ExprTool:
223
224
  日期字段名
224
225
  asset:str
225
226
  资产字段名
226
- alias: Dict[str,str]
227
- 符号别名。可以变通的传入正则符号名
228
227
  extra_codes: Sequence[object]
229
228
  需要复制到模板中的额外代码
230
229
 
@@ -266,11 +265,11 @@ class ExprTool:
266
265
 
267
266
  codes = codegen(exprs_ldl, exprs_src, syms_dst,
268
267
  filename=template_file, date=date, asset=asset,
269
- alias=alias,
270
268
  extra_codes=extra_codes,
269
+ table_name=table_name,
271
270
  **kwargs)
272
271
 
273
- logger.info(f'code is generated')
272
+ logger.info(f'{style} code is generated')
274
273
 
275
274
  if format:
276
275
  # 格式化。在遗传算法中没有必要
@@ -287,6 +286,7 @@ class ExprTool:
287
286
  style: Literal['pandas', 'polars_group', 'polars_over', 'sql'] = 'polars_over',
288
287
  template_file: Optional[str] = None,
289
288
  date: str = 'date', asset: str = 'asset',
289
+ table_name: str = 'self',
290
290
  **kwargs) -> str:
291
291
  """通过字符串生成代码, 加了缓存,多次调用不重复生成"""
292
292
  raw, exprs_list = sources_to_exprs(self.globals_, source, *more_sources, convert_xor=convert_xor)
@@ -300,6 +300,7 @@ class ExprTool:
300
300
  # 传入多个列的方法
301
301
  extra_codes,
302
302
  ),
303
+ table_name=table_name,
303
304
  **kwargs)
304
305
 
305
306
  # 移回到cache,防止多次调用多次保存
@@ -316,8 +317,8 @@ class ExprTool:
316
317
 
317
318
 
318
319
  @lru_cache(maxsize=64, typed=True)
319
- def _get_func_from_code(code: str):
320
- logger.info(f'get func from code')
320
+ def _get_func_from_code_py(code: str):
321
+ logger.info(f'get func from code py')
321
322
  globals_ = {}
322
323
  exec(code, globals_)
323
324
  return globals_['main']
@@ -332,7 +333,7 @@ def _get_func_from_module(module: str):
332
333
 
333
334
 
334
335
  @lru_cache(maxsize=64, typed=True)
335
- def _get_func_from_file(file: str):
336
+ def _get_func_from_file_py(file: str):
336
337
  file = pathlib.Path(file)
337
338
  logger.info(f'get func from file "{file.absolute()}"')
338
339
  with open(file, 'r', encoding='utf-8') as f:
@@ -341,6 +342,14 @@ def _get_func_from_file(file: str):
341
342
  return globals_['main']
342
343
 
343
344
 
345
+ @lru_cache(maxsize=64, typed=True)
346
+ def _get_code_from_file(file: str):
347
+ file = pathlib.Path(file)
348
+ logger.info(f'get code from file "{file.absolute()}"')
349
+ with open(file, 'r', encoding='utf-8') as f:
350
+ return f.read()
351
+
352
+
344
353
  _TOOL_ = ExprTool()
345
354
 
346
355
 
@@ -354,14 +363,15 @@ def codegen_exec(df: Optional[DataFrame],
354
363
  style: Literal['pandas', 'polars_group', 'polars_over', 'sql'] = 'polars_over',
355
364
  template_file: Optional[str] = None,
356
365
  date: str = 'date', asset: str = 'asset',
357
-
358
- **kwargs) -> Optional[DataFrame]:
366
+ table_name: str = 'self',
367
+ **kwargs) -> Union[DataFrame, str, None]:
359
368
  """快速转换源代码并执行
360
369
 
361
370
  Parameters
362
371
  ----------
363
- df: pl.DataFrame, pd.DataFrame, pl.LazyFrame
364
- 输入DataFrame
372
+ df: pl.DataFrame, pd.DataFrame, pl.LazyFrame,None
373
+ 输入DataFrame,输出DataFrame
374
+ 输入None,输出代码
365
375
  codes:
366
376
  函数体。此部分中的表达式会被翻译成目标代码
367
377
  extra_codes: str
@@ -392,10 +402,15 @@ def codegen_exec(df: Optional[DataFrame],
392
402
  - partition_by: 空值划分到不同分区
393
403
  - order_by: 空值排同一分区的前排
394
404
  - None: 不做处理
405
+ table_name:str
406
+ 表名。style=sql时有效
395
407
 
396
408
  Returns
397
409
  -------
398
410
  DataFrame
411
+ 输出DataFrame
412
+ str
413
+ 输出代码
399
414
 
400
415
  Notes
401
416
  -----
@@ -406,16 +421,24 @@ def codegen_exec(df: Optional[DataFrame],
406
421
 
407
422
  """
408
423
  if df is not None:
424
+ input_file = None
409
425
  # 以下代码都带缓存功能
410
426
  if run_file is True:
411
427
  assert output_file is not None, 'output_file is required'
412
- return _get_func_from_file(output_file)(df)
413
- if run_file is not False:
414
- run_file = str(run_file)
415
- if run_file.endswith('.py'):
416
- return _get_func_from_file(run_file)(df)
428
+ input_file = str(output_file)
429
+ elif run_file is not False:
430
+ input_file = str(run_file)
431
+
432
+ if input_file is not None:
433
+ if input_file.endswith('.py'):
434
+ return _get_func_from_file_py(input_file)(df)
435
+ elif input_file.endswith('.sql'):
436
+ ctx = pl.SQLContext(frames={table_name: df})
437
+ return ctx.execute(_get_code_from_file(input_file), eager=isinstance(df, _pl_DataFrame))
417
438
  else:
418
- return _get_func_from_module(run_file)(df) # 可断点调试
439
+ return _get_func_from_module(input_file)(df) # 可断点调试
440
+ else:
441
+ pass
419
442
 
420
443
  # 此代码来自于sympy.var
421
444
  frame = inspect.currentframe().f_back
@@ -432,11 +455,16 @@ def codegen_exec(df: Optional[DataFrame],
432
455
  style=style, template_file=template_file,
433
456
  date=date, asset=asset,
434
457
  over_null=over_null,
458
+ table_name=table_name,
435
459
  **kwargs
436
460
  )
437
461
 
438
462
  if df is None:
439
- return None
463
+ # 如果df为空,直接返回代码
464
+ return code
465
+ elif style == 'sql':
466
+ ctx = pl.SQLContext(frames={table_name: df})
467
+ return ctx.execute(code, eager=isinstance(df, _pl_DataFrame))
440
468
  else:
441
469
  # 代码一样时就从缓存中取出函数
442
- return _get_func_from_code(code)(df)
470
+ return _get_func_from_code_py(code)(df)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: expr_codegen
3
- Version: 0.12.0
3
+ Version: 0.12.1
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.12.0"
File without changes
File without changes
File without changes