【发布时间】:2016-03-24 00:20:46
【问题描述】:
我的网站运行这个 Python 脚本,如果使用 Cython,它会更加优化。最近我需要添加Sympy with Lambdify,这与Cython 不太好。
所以我将问题简化为一个最小的工作示例。在代码中,我有一个带有字符串键的字典,其中的值是列表。我想将这些键用作变量。在下面的简化示例中,只有 1 个变量,但通常我需要更多。请检查以下示例:
import numpy as np
from sympy.parsing.sympy_parser import parse_expr
from sympy.utilities.lambdify import lambdify, implemented_function
from sympy import S, Symbol
from sympy.utilities.autowrap import ufuncify
def CreateMagneticFieldsList(dataToSave,equationString,DSList):
expression = S(equationString)
numOfElements = len(dataToSave["MagneticFields"])
#initialize the magnetic field output array
magFieldsArray = np.empty(numOfElements)
magFieldsArray[:] = np.NaN
lam_f = lambdify(tuple(DSList),expression,modules='numpy')
try:
# pass
for i in range(numOfElements):
replacementList = np.zeros(len(DSList))
for j in range(len(DSList)):
replacementList[j] = dataToSave[DSList[j]][i]
try:
val = np.double(lam_f(*replacementList))
except:
val = np.nan
magFieldsArray[i] = val
except:
print("Error while evaluating the magnetic field expression")
return magFieldsArray
list={"MagneticFields":[1,2,3,4,5]}
out=CreateMagneticFieldsList(list,"MagneticFields*5.1",["MagneticFields"])
print(out)
我们称之为test.py。这很好用。现在我想对它进行cythonize,所以我使用以下脚本:
#!/bin/bash
cython --embed -o test.c test.py
gcc -pthread -fPIC -fwrapv -Ofast -Wall -L/lib/x86_64-linux-gnu/ -lpython3.4m -I/usr/include/python3.4 -o test.exe test.c
现在如果我执行./test.exe,它会抛出异常!这是一个例外:
Traceback (most recent call last):
File "test.py", line 42, in init test (test.c:1811)
out=CreateMagneticFieldsList(list,"MagneticFields*5.1",["MagneticFields"])
File "test.py", line 19, in test.CreateMagneticFieldsList (test.c:1036)
lam_f = lambdify(tuple(DSList),expression,modules='numpy')
File "/usr/local/lib/python3.4/dist-packages/sympy/utilities/lambdify.py", line 363, in lambdify
callers_local_vars = inspect.currentframe().f_back.f_locals.items()
AttributeError: 'NoneType' object has no attribute 'f_locals'
所以问题是:如何让lambdify 与Cython 一起工作?
注意事项:我想指出我有 Debian Jessie,这就是我使用 Python 3.4 的原因。另外我想指出,在不使用 lambdify 时,我对 Cython 没有任何问题。另外我想指出,Cython 已更新到最新版本,pip3 install cython --upgrade。
【问题讨论】:
-
据我所见,
--embed不是魔术,也不会做优化(它只是从libpython调用解释器),所以几乎不需要这样做。目的是什么? -
@ivan_pozdeev 嗯,它比原始 Python 快得多...您是否建议删除
--embed? -
可能相关,cython docs - limitations“目前我们生成虚假回溯作为异常传播的一部分,但不要填写本地,也无法填写 co_code。”
-
@J.J.Hakala 将此作为答案发布,因为它很可能是它。
标签: python optimization cython sympy lambdify