有没有办法腌制scipy.interpolate.Rbf()对象?

2024-06-30 07:52:17 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在为一个相当大的数据集创建一个径向基函数插值模型。主要任务`scipy.interpolate.Rbf(,)需要大约1分钟和14GB的RAM。 因为并不是每一台机器都能运行这个程序,而且程序经常运行在同一个数据集上,所以我想把结果保存到一个文件中。这是一个简化的例子:

import scipy.interpolate as inter
import numpy as np
import cPickle

x = np.array([[1,2,3],[3,4,5],[7,8,9],[1,5,9]])
y = np.array([1,2,3,4])

rbfi = inter.Rbf(x[:,0], x[:,1], x[:,2], y)

RBFfile = open('picklefile','wb')
RBFpickler = cPickle.Pickler(RBFfile,protocol=2)
RBFpickler.dump(rbfi)
RBFfile.close()

RBFpickler.dump()调用导致can't pickle <type 'instancemethod'>错误。 据我所知,这意味着其中某处有一个方法(嗯,rbfi()是可调用的),而且由于某些我不太理解的原因,它不能被pickle。在

有没有人知道一种方法可以用其他方法来处理这个问题,或者用另一种方法保存inter.Rbf()调用的结果?在

其中有一些shape(nd,n)和(n,n)数组(rbfi.Arbfi.xirbfi.di…),我假设它们存储了所有有趣的信息。我想我不能再把这些数组放在一起。。。在

编辑: 附加约束:不允许我在系统上安装其他库。如果我可以用Python来包含它们,那么我只能用纯Python编译它们。在


Tags: 数据方法import程序asnpscipyarray
2条回答

好吧,迈克的解决方案似乎很好,但同时我发现了另一个:

Rbf对象只有两个部分不能直接进行pickle,而且它们很容易从头创建。因此,我的代码现在只保存数据部分:

import scipy.interpolate as inter
import numpy as np
import cPickle

x = np.array([[1,2,3],[3,4,5],[7,8,9],[1,5,9]])
y = np.array([1,2,3,4])

rbfi = inter.Rbf(x[:,0], x[:,1], x[:,2], y)

RBFfile = open('picklefile','wb')
RBFpickler = cPickle.Pickler(RBFfile,protocol=2)

# RBF can't be pickled directly, so save everything required for reconstruction
RBFdict = {}            
for key in rbfi.__dict__.keys():
    if key != '_function' and key!= 'norm':
        RBFdict[key] = rbfi.__getattribute__(key)   

RBFpickler.dump(RBFdict)
RBFfile.close()

这给了我一个包含对象中存储的所有信息的文件。rbfi._function()rbfi.norm不保存。幸运的是,只要初始化任何(任意简单的)Rbf对象,就可以从头开始重新创建它们:

^{pr2}$

然后,此对象的数据部分将替换为保存的数据:

RBFfile = open('picklefile','rb')
RBFunpickler = cPickle.Unpickler(RBFfile)
RBFdict = RBFunpickler.load()
RBFfile.close()

## replace rbfi's contents with what was saved ##
for key,value in RBFdict.iteritems():
    rbfi.__setattr__(key, value)

>>> rbfi(2,3,4)
array(1.4600661386382146)

显然,甚至没有必要给新的Rbf对象提供与原始对象相同的维数,因为所有这些都将被覆盖。在

也就是说,Mike的解决方案可能是更普遍适用的解决方案,而这个方案更独立于平台。我有过在平台之间移动pickled Kriging模型的问题,但是这种RBF模型的方法似乎更健壮,但是我还没有对它进行过太多的测试,所以没有给出任何保证。在

我会使用dill来序列化结果……或者如果你想要一个缓存函数,你可以使用klepto来缓存函数调用,这样就可以最大限度地减少对函数的重新评估。在

Python 2.7.6 (default, Nov 12 2013, 13:26:39) 
[GCC 4.2.1 Compatible Apple Clang 4.1 ((tags/Apple/clang-421.11.66))] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import scipy.interpolate as inter
>>> import numpy as np
>>> import dill
>>> import klepto
>>> 
>>> x = np.array([[1,2,3],[3,4,5],[7,8,9],[1,5,9]])
>>> y = np.array([1,2,3,4])
>>> 
>>> # build an on-disk archive for numpy arrays,
>>> # with a dictionary-style interface  
>>> p = klepto.archives.dir_archive(serialized=True, fast=True)
>>> # add a caching algorithm, so when threshold is hit,
>>> # memory is dumped to disk
>>> c = klepto.safe.lru_cache(cache=p)
>>> # decorate the target function with the cache
>>> c(inter.Rbf)
<function Rbf at 0x104248668>
>>> rbf = _
>>> 
>>> # 'rbf' is now cached, so all repeat calls are looked up
>>> # from disk or memory
>>> d = rbf(x[:,0], x[:,1], x[:,2], y)
>>> d
<scipy.interpolate.rbf.Rbf object at 0x1042454d0>
>>> d.A
array([[ 1.        ,  1.22905719,  2.36542472,  1.70724365],
       [ 1.22905719,  1.        ,  1.74422655,  1.37605151],
       [ 2.36542472,  1.74422655,  1.        ,  1.70724365],
       [ 1.70724365,  1.37605151,  1.70724365,  1.        ]])
>>> 

继续

^{pr2}$

获取klepto和{}这里:https://github.com/uqfoundation

相关问题 更多 >