2015-07-09 14 views
6

Tiêu đề nói lên tất cả. Có cách nào để serialize một chức năng được tạo ra bởi sympy.lambdify ?:Làm thế nào để serialize chức năng lambpyified sympy?

import sympy as sym 
import pickle 
import dill 
a, b = sym.symbols("a, b") 
expr = sym.sin(a) + sym.cos(b) 
lambdified_expr = sym.lambdify((a, b), expr, modules="numpy") 
pickle.dumps(lambdified_expr) # won't work 
dill.dumps(lambdified_expr) # won't work either 

... Lý do tôi muốn làm điều này là bởi vì mã của tôi tạo ra rất nhiều chức năng lambdified nhưng tôi thấy nó mất nhiều thời gian mỗi khi .

Trả lời

4

Bạn thực sự có thể sử dụng dill để dưa nó. Các phiên bản gần đây nhất của dill (ví dụ: trên github) có "cài đặt" cho phép các biến thể của cách dưa được xây dựng trên dump. Có, cài đặt mặc định cho dill không thành công trên đối tượng này, nhưng không phải nếu bạn sử dụng cài đặt theo dõi đệ quy các tham chiếu toàn cục (tức là recurse = True). Cài đặt này tương tự như những gì cloudpickle cung cấp cho bạn theo mặc định.

>>> import sympy as sym 
>>> import pickle 
>>> import dill 
>>> a, b = symbols("a, b") 
>>> a, b = sym.symbols("a, b") 
>>> expr = sym.sin(a) + sym.cos(b) 
>>> lambdified_expr = sym.lambdify((a, b), expr, modules="numpy") 
>>> 
>>> dill.settings 
{'recurse': False, 'byref': False, 'protocol': 2, 'fmode': 0} 
>>> dill.settings['recurse'] = True 
>>> dill.dumps(lambdified_expr) 
'\x80\x02cdill.dill\n_create_function\nq\x00(cdill.dill\n_unmarshal\nq\x01U\x83c\x02\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00C \x00\x00s\x14\x00\x00\x00t\x00\x00|\x00\x00\x83\x01\x00t\x01\x00|\x01\x00\x83\x01\x00\x17S(\x01\x00\x00\x00N(\x02\x00\x00\x00t\x03\x00\x00\x00sint\x03\x00\x00\x00cos(\x02\x00\x00\x00t\x01\x00\x00\x00at\x01\x00\x00\x00b(\x00\x00\x00\x00(\x00\x00\x00\x00s\x08\x00\x00\x00<string>t\x08\x00\x00\x00<lambda>\x01\x00\x00\x00s\x00\x00\x00\x00q\x02\x85q\x03Rq\x04}q\x05(U\x03cosq\x06cnumpy.core.umath\ncos\nq\x07U\x03sinq\x08cnumpy.core.umath\nsin\nq\tuU\x08<lambda>q\nNN}q\x0btq\x0cRq\r.' 

P.S. Tôi là tác giả của dill, vì vậy tôi biết.

+0

lý do tại sao recurse = True không phải là tùy chọn mặc định? – denfromufa

+1

Vì 'dill' có thể tuần tự hóa một loạt các đối tượng và' recurse = False' cung cấp phạm vi phủ sóng rộng nhất. Nếu bạn sử dụng 'recurse = True', nó hoạt động thực sự tốt cho các đối tượng nhất định, nhưng phá vỡ serialization cho một số trường hợp. Nếu (hoặc khi nào) tôi giải quyết các trường hợp nó bị hỏng, sau đó nó sẽ trở thành mặc định. Cho đến lúc đó, lựa chọn tốt nhất là * không * xóa chức năng mặc định, nhưng cung cấp chức năng mới thông qua cài đặt. Xem: https://github.com/uqfoundation/dill/issues/105 –

+0

@MikeMcKerns Tôi có một cảnh báo trước, đối với các hàm lambadified hợp lý lớn, tôi nhận được 'RuntimeError: độ sâu đệ quy tối đa vượt quá khi gọi một đối tượng Python'. –

2

Thật vậy - dưa, cPickle và thậm chí là thì là không thành công trên ví dụ này với cài đặt mặc định.

Nhưng đám mây không bị lỗi!

pip install cloudpickle 

hoặc

https://github.com/cloudpipe/cloudpickle

import sympy as sym 
from cloudpickle import dumps, loads 
a, b = sym.symbols("a, b") 
expr = sym.sin(a) + sym.cos(b) 
lambdified_expr = sym.lambdify((a, b), expr, modules="numpy") 
var=dumps(lambdified_expr) 
a1=lambdified_expr(10,10) 
del lambdified_expr 
lambdified_expr=loads(var) 
a2=lambdified_expr(10,10) 
a1==a2 # True 
Các vấn đề liên quan