保存 Scipy 的插值输出
Save Interpolation output from Scipy
我有一个问题,我需要使用例如插值 3D 函数SciPy,然后保存这个插值的输出以备将来使用。也就是说,我不想每次都必须 运行 插值过程,因为生成要插值的 3D 函数在计算上要求很高(它来自 Biot-Savart 定律,所以很多数值积分也是如此)。
但是,我无法理解这是否可行,其次,如何实现它。从我在其他一些帖子上看到的,应该是可以的,但解决方案似乎对我不起作用。
我写了下面的测试代码,但是在测试的时候出现如下错误:
TypeError: 'numpy.ndarray' object is not callable
此错误发生在函数 loadInterpolation()
中开始 zeroVal
的代码行上。根据我之前阅读的内容,我希望 allow_pickle=True
能够解决这个问题
.
import scipy
from scipy.interpolate import RegularGridInterpolator
def f(x,y,z):
field = -x**2-y**2+z**2
return field
def performSaveInterpolation():
print(scipy.__version__)
print('Performing Interpolation...')
x = np.linspace(-1,1,100)
y = np.linspace(-1,1,100)
z = np.linspace(-1,1,100)
xg, yg ,zg = np.meshgrid(x, y, z, indexing='ij', sparse=True)
data = f(xg,yg,zg)
my_interpolating_function = RegularGridInterpolator((x, y, z), data)
zeroVal = my_interpolating_function([0,0,0])
oneVal = my_interpolating_function([1,1,1])
print('Interpolated function @ (0,0,0): ' + str(zeroVal))
print('Interpolated function @ (1,1,1): ' + str(oneVal))
np.save('interpolation.npy',my_interpolating_function,allow_pickle=True)
return 0
def loadInterpolation():
print('Loading Interpolation...')
interpolationFunc = np.load('interpolation.npy',allow_pickle=True)
zeroVal = interpolationFunc([0,0,0])
oneVal = interpolationFunc([1,1,1])
print('Interpolated function @ (0,0,0): ' + str(zeroVal))
print('Interpolated function @ (1,1,1): ' + str(oneVal))
return 0
performSaveInterpolation()
loadInterpolation()
为什么不直接使用 pickle 呢?链接到问题:How-can-i-use-pickle-to-save-a-dict.
Pickle 应该能够序列化 任何可能类型 的 python 对象。不仅 numpy 数组(至于 numpy save 函数是 只有 能够做到。它不能保存除 np.arrays 之外的其他对象类型,并且迭代函数不是 numpy.ndarray
类型,因此错误)
像这样使用它:
TLDR :
import pickle
with open('mypicklefile.pck', 'wb') as file_handle:
pickle.dump(my_saved_object, file_handle)
然后 :
with open('mypicklefile.pck', 'rb') as file_handle:
my_loaded_object = pickle.load(file_handle)
如果您需要一次序列化多个对象,例如您的函数,以及zeroVal
和oneVal
以避免提取它们每次从函数中,您可以:
解决方案 1
对同一个文件进行多次序列化:
with open('mypicklefile.pck', 'wb') as file_handle:
pickle.dump(my_saved_object, file_handle)
pickle.dump(my_saved_object2, file_handle)
pickle.dump(my_saved_object3, file_handle)
然后反序列化多次(顺序很重要!你必须“记住”哪个对象是哪个)
with open('mypicklefile.pck', 'rb') as file_handle:
my_loaded_object = pickle.load(file_handle)
my_loaded_object2 = pickle.load(file_handle)
my_loaded_object3 = pickle.load(file_handle)
解决方案 2
或者,(IMO 更好的解决方案)使用字典,每个对象都有一点元数据,因为它有一个名称(键):
mydata = {"tiny_description": my_saved_object, "something_more" : my_saved_object2}
with open('mypicklefile.pck', 'wb') as file_handle:
pickle.dump(mydata , file_handle)
with open('mypicklefile.pck', 'rb') as file_handle:
temp_dict = pickle.load(file_handle)
tiny_description = temp_dict["tiny_description"]
something_more = emp_dict["something_more"]
我有一个问题,我需要使用例如插值 3D 函数SciPy,然后保存这个插值的输出以备将来使用。也就是说,我不想每次都必须 运行 插值过程,因为生成要插值的 3D 函数在计算上要求很高(它来自 Biot-Savart 定律,所以很多数值积分也是如此)。
但是,我无法理解这是否可行,其次,如何实现它。从我在其他一些帖子上看到的,应该是可以的,但解决方案似乎对我不起作用。
我写了下面的测试代码,但是在测试的时候出现如下错误:
TypeError: 'numpy.ndarray' object is not callable
此错误发生在函数 loadInterpolation()
中开始 zeroVal
的代码行上。根据我之前阅读的内容,我希望 allow_pickle=True
能够解决这个问题
.
import scipy
from scipy.interpolate import RegularGridInterpolator
def f(x,y,z):
field = -x**2-y**2+z**2
return field
def performSaveInterpolation():
print(scipy.__version__)
print('Performing Interpolation...')
x = np.linspace(-1,1,100)
y = np.linspace(-1,1,100)
z = np.linspace(-1,1,100)
xg, yg ,zg = np.meshgrid(x, y, z, indexing='ij', sparse=True)
data = f(xg,yg,zg)
my_interpolating_function = RegularGridInterpolator((x, y, z), data)
zeroVal = my_interpolating_function([0,0,0])
oneVal = my_interpolating_function([1,1,1])
print('Interpolated function @ (0,0,0): ' + str(zeroVal))
print('Interpolated function @ (1,1,1): ' + str(oneVal))
np.save('interpolation.npy',my_interpolating_function,allow_pickle=True)
return 0
def loadInterpolation():
print('Loading Interpolation...')
interpolationFunc = np.load('interpolation.npy',allow_pickle=True)
zeroVal = interpolationFunc([0,0,0])
oneVal = interpolationFunc([1,1,1])
print('Interpolated function @ (0,0,0): ' + str(zeroVal))
print('Interpolated function @ (1,1,1): ' + str(oneVal))
return 0
performSaveInterpolation()
loadInterpolation()
为什么不直接使用 pickle 呢?链接到问题:How-can-i-use-pickle-to-save-a-dict.
Pickle 应该能够序列化 任何可能类型 的 python 对象。不仅 numpy 数组(至于 numpy save 函数是 只有 能够做到。它不能保存除 np.arrays 之外的其他对象类型,并且迭代函数不是 numpy.ndarray
类型,因此错误)
像这样使用它:
TLDR :
import pickle
with open('mypicklefile.pck', 'wb') as file_handle:
pickle.dump(my_saved_object, file_handle)
然后 :
with open('mypicklefile.pck', 'rb') as file_handle:
my_loaded_object = pickle.load(file_handle)
如果您需要一次序列化多个对象,例如您的函数,以及zeroVal
和oneVal
以避免提取它们每次从函数中,您可以:
解决方案 1
对同一个文件进行多次序列化:
with open('mypicklefile.pck', 'wb') as file_handle:
pickle.dump(my_saved_object, file_handle)
pickle.dump(my_saved_object2, file_handle)
pickle.dump(my_saved_object3, file_handle)
然后反序列化多次(顺序很重要!你必须“记住”哪个对象是哪个)
with open('mypicklefile.pck', 'rb') as file_handle:
my_loaded_object = pickle.load(file_handle)
my_loaded_object2 = pickle.load(file_handle)
my_loaded_object3 = pickle.load(file_handle)
解决方案 2
或者,(IMO 更好的解决方案)使用字典,每个对象都有一点元数据,因为它有一个名称(键):
mydata = {"tiny_description": my_saved_object, "something_more" : my_saved_object2}
with open('mypicklefile.pck', 'wb') as file_handle:
pickle.dump(mydata , file_handle)
with open('mypicklefile.pck', 'rb') as file_handle:
temp_dict = pickle.load(file_handle)
tiny_description = temp_dict["tiny_description"]
something_more = emp_dict["something_more"]