【问题标题】:Save scipy object to file将 scipy 对象保存到文件
【发布时间】:2016-04-21 02:23:09
【问题描述】:

我想将scipy.interpolate.InterpolatedUnivariateSpline生成的对象interpolator保存到一个文件中,以便之后加载并使用它。 这是控制台上的结果:

>>> interpolator
 <scipy.interpolate.fitpack2.InterpolatedUnivariateSpline object at 0x11C27170>
np.save("interpolator",np.array(interpolator))
>>> f = np.load("interpolator.npy")
>>> f
array(<scipy.interpolate.fitpack2.InterpolatedUnivariateSpline object at 0x11C08FB0>, dtype=object)

这些是尝试使用具有通用值的加载插值器f 的结果:

>>>f(10)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'numpy.ndarray' object is not callable

或:

>>> f[0](10)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IndexError: too many indices for array

如何正确保存/加载它?

【问题讨论】:

  • 它在一个 0d 数组中。试试f[()]f.item()

标签: python numpy scipy interpolation


【解决方案1】:

interpolator 对象不是数组,因此np.save 将其包装在object 数组中。它依靠pickle 来保存不是数组的元素。所以你得到一个包含一个对象的 0d 数组。

用一个简单的字典对象来说明:

In [280]: np.save('test.npy',{'one':1})
In [281]: x=np.load('test.npy')
In [282]: x
Out[282]: array({'one': 1}, dtype=object)
In [283]: x[0]
...
IndexError: 0-d arrays can't be indexed
In [284]: x[()]
Out[284]: {'one': 1}
In [285]: x.item()
Out[285]: {'one': 1}
In [288]: x.item()['one']
Out[288]: 1

所以item[()] 都会从数组中检索这个对象。然后您应该能够像在save 之前一样使用它。

使用您自己的pickle 调用很好。

【讨论】:

  • 嗨@hpaulj,根据OP的问题,您的回答要好得多。我还没有真正见过 0D 数组,就 numpy.load 而言,返回具有单个元素的一维数组不是更直观吗?
【解决方案2】:

它看起来像 numpy.save 然后 numpy.load 将 scipy InterpolatedUnivariateSpline 对象转换为 numpy 对象。 Numpy 保存/加载apparently 有一个allow_pickle=True 输入,应该保留对象信息。这在我的 numpy 版本(1.9.2)中不存在,我假设你的版本也可能。使用spl=numpy.load("file"),类型信息会丢失,因此作为方法调用spl 会失败。由于 numpy save 主要是为二进制数据数组设计的,所以最通用的解决方案可能是使用pickle。举个最简单的例子,

import matplotlib.pyplot as plt
from scipy.interpolate import InterpolatedUnivariateSpline
import numpy as np
try:
    import cPickle as pickle
except ImportError:
    import pickle

x = np.linspace(-3, 3, 50)
y = np.exp(-x**2) + 0.1 * np.random.randn(50)
spl = InterpolatedUnivariateSpline(x, y)
plt.plot(x, y, 'ro', ms=5)


xs = np.linspace(-3, 3, 1000)

#Plot before save
plt.plot(xs, spl(xs), 'g', lw=3, alpha=0.7)

#Save, load and plot again (NOTE CAUSES ERROR)
#np.save("interpolator",spl)
#spl_loaded = np.load("interpolator.npy")
#plt.plot(xs, spl_loaded(xs), 'k--', lw=3, alpha=0.7)

#Pickle, unpickle and then plot again
with open('interpolator.pkl', 'wb') as f:
    pickle.dump(spl, f)
with open('interpolator.pkl', 'rb') as f:
    spl_loaded = pickle.load(f)
plt.plot(xs, spl_loaded(xs), 'k--', lw=3, alpha=0.7)

plt.show()

【讨论】:

  • np.save 将 pickle 用于无法直接保存的内容。在 OP 案例中,它首先将其包装在一个对象数组中。
猜你喜欢
  • 2016-08-15
  • 2013-12-27
  • 2020-11-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-02-22
  • 2019-05-19
  • 2013-02-09
相关资源
最近更新 更多