8

尝试使用非常有用的 pandas 将数据处理为时间序列,我现在绊倒了这样一个事实,即似乎不存在可以直接插值(使用样条线或类似物)对 DateTime 作为 x-的数据的库轴?我似乎总是被迫首先转换为一些浮点数,比如自 1980 年以来的秒数或类似的东西。

到目前为止,我一直在尝试以下事情,对于奇怪的格式感到抱歉,我只有在 ipython 笔记本中有这些东西,而且我无法从那里复制单元格:

from scipy.interpolate import InterpolatedUnivariateSpline as IUS
type(bb2temp): pandas.core.series.TimeSeries
s = IUS(bb2temp.index.to_pydatetime(), bb2temp, k=1)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-67-19c6b8883073> in <module>()
----> 1 s = IUS(bb2temp.index.to_pydatetime(), bb2temp, k=1)

/Library/Frameworks/EPD64.framework/Versions/7.3/lib/python2.7/site-packages/scipy/interpolate/fitpack2.py in __init__(self, x, y, w, bbox, k)
    335         #_data == x,y,w,xb,xe,k,s,n,t,c,fp,fpint,nrdata,ier
    336         self._data = dfitpack.fpcurf0(x,y,k,w=w,
--> 337                                       xb=bbox[0],xe=bbox[1],s=0)
    338         self._reset_class()
    339 

TypeError: float() argument must be a string or a number

通过使用bb2temp.index.values(看起来像这样:

array([1970-01-15 184:00:35.884999, 1970-01-15 184:00:58.668999,
       1970-01-15 184:01:22.989999, 1970-01-15 184:01:45.774000,
       1970-01-15 184:02:10.095000, 1970-01-15 184:02:32.878999,
       1970-01-15 184:02:57.200000, 1970-01-15 184:03:19.984000,

) 作为 x 参数,有趣的是,Spline 类确实创建了一个插值器,但在尝试插值/外推到更大的 DateTimeIndex 时它仍然会中断(这是我在这里的最终目标)。看起来是这样的:

all_times = divcal.timed.index.levels[2] # part of a MultiIndex

all_times
<class 'pandas.tseries.index.DatetimeIndex'>
[2009-07-20 00:00:00.045000, ..., 2009-07-20 00:30:00.018000]
Length: 14063, Freq: None, Timezone: None

s(all_times.values) # applying the above generated interpolator
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-74-ff11f6d6d7da> in <module>()
----> 1 s(tall.values)

/Library/Frameworks/EPD64.framework/Versions/7.3/lib/python2.7/site-packages/scipy/interpolate/fitpack2.py in __call__(self, x, nu)
    219 #            return dfitpack.splev(*(self._eval_args+(x,)))
    220 #        return dfitpack.splder(nu=nu,*(self._eval_args+(x,)))
--> 221         return fitpack.splev(x, self._eval_args, der=nu)
    222 
    223     def get_knots(self):

/Library/Frameworks/EPD64.framework/Versions/7.3/lib/python2.7/site-packages/scipy/interpolate/fitpack.py in splev(x, tck, der, ext)
    546 
    547         x = myasarray(x)
--> 548         y, ier =_fitpack._spl_(x, der, t, c, k, ext)
    549         if ier == 10:
    550             raise ValueError("Invalid input data")

TypeError: array cannot be safely cast to required type

我尝试使用s(all_times)ands(all_times.to_pydatetime())以及相同的TypeError: array cannot be safely cast to required type.

可悲的是,我是正确的吗?是否每个人都习惯于将时间转换为浮点数,以至于没有人认为这些插值应该自动工作是个好主意?(我最终会找到一个超级有用的项目来贡献..)或者你想证明我错了并获得一些 SO 积分?;)

编辑:警告:在将其交给插值例程之前,请检查您的 Pandas 数据中的 NaN。他们不会抱怨任何事情,只会默默地失败。

4

1 回答 1

8

问题是那些在下面使用的 fitpack 例程需要浮动。因此,在某些时候必须从日期时间转换为浮点数。这种转换很容易。如果bb2temp.index.values是您的日期时间数组,只需执行以下操作:

In [1]: bb2temp.index.values.astype('d')
Out[1]: 
array([  1.22403588e+12,   1.22405867e+12,   1.22408299e+12,
         1.22410577e+12,   1.22413010e+12,   1.22415288e+12,
         1.22417720e+12,   1.22419998e+12])

你只需要把它传递给你的样条线。并且要将结果转换回日期时间对象,您可以执行results.astype('datetime64').

于 2012-12-18T21:44:00.597 回答