Python, Pandas;ValueError('窗口大小必须是整数',)

11

我在 Bokeh 回调函数中使用 Pandas 代码时遇到了问题。

以下是错误发生前的部分输出。我的数据框看起来正常,但我不确定为什么会出错。

                     time  temperature
0 2016-03-17 11:00:00        4.676
1 2016-03-17 11:30:00        4.633
2 2016-03-17 12:00:00        4.639
3 2016-03-17 12:30:00        4.603
4 2016-03-17 13:00:00        4.615
5 2016-03-17 13:30:00        4.650
6 2016-03-17 14:00:00        4.678
7 2016-03-17 14:30:00        4.698
8 2016-03-17 15:00:00        4.753
9 2016-03-17 15:30:00        4.847
ERROR:bokeh.server.protocol_handler:error handling message Message 'PATCH-DOC' (
revision 1): ValueError('window must be an integer',)

以下是我从flask嵌入式示例(链接在此)更改的代码:

def callback(attr, old, new):
        df = pd.DataFrame.from_dict(source.data.copy())
        print df[:10]
        if new == 0:
            data = df
        else:
            data = df.rolling('{0}D'.format(new)).mean()
        source.data = ColumnDataSource(data=data).data

    slider = Slider(start=0, end=30, value=0, step=1, title="Smoothing by N Days")
    slider.on_change('value', callback)

如果有帮助的话,我也可以包含完整的代码,但是我主要的更改只是使用doc.add_periodic_callback()定期获取新数据。

3个回答

8
截至今天,文档的说明如下:

window : int 或 offset

移动窗口大小。这是用于计算统计量的观察值数量。每个窗口将是固定大小。

如果它是一个偏移量,则这将是每个窗口的时间段。每个窗口将基于包含在时间段中的观察值而变化大小。这仅适用于datetimelike索引。这是0.19.0中的新功能。

我不确定您的数据帧中的时间信息是列还是MultiIndex的一部分。对于第一种情况,您可以使用.set_index('time')
对于MultiIndex,目前您无法使用offsets。 请参阅相关问题。相反,您可以使用.reset_index()将其转换为单个索引数据帧(请参见此处)。
更新:您还可以通过on参数传递datetime列以进行基于偏移的滚动度量(因此,您不必将它们放在索引中)。

1
.set_index('time') 修复了我的数据框,问题解决了,然后使用 mean()。 - pbaranski

7

df.rolling 还可以处理时间段。确保日期时间格式为 pandas 格式。如果不是,请进行转换 -

data['col'] = pd.to_datetime(data['col'])

3
确保将其转换为日期时间类型,然后在该列上运行“set_index”。这对我有用。 - Oer

3
这是Pandas的一个错误。您正在向df.rolling传递一个字符串,但它只接受整数值。您可能想要传递int(new)

编辑:如下所述,显然Pandas文档不完整,在这种情况下真正的最终问题可能是缺少时间索引,因为创建一个naive Dataframe并传递像"10d"这样的值肯定会引发所示的错误:

In [2]: df = pd.DataFrame({'B': [0, 1, 2, 10, 4]})

In [3]: df.rolling('10d')
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-3-2a9875316cd7> in <module>
----> 1 df.rolling('10d')

~/anaconda/lib/python3.7/site-packages/pandas/core/generic.py in rolling(self, window, min_periods, center, win_type, on, axis, closed)
   8906                                    min_periods=min_periods,
   8907                                    center=center, win_type=win_type,
-> 8908                                    on=on, axis=axis, closed=closed)
   8909
   8910         cls.rolling = rolling

~/anaconda/lib/python3.7/site-packages/pandas/core/window.py in rolling(obj, win_type, **kwds)
   2467         return Window(obj, win_type=win_type, **kwds)
   2468
-> 2469     return Rolling(obj, **kwds)
   2470
   2471

~/anaconda/lib/python3.7/site-packages/pandas/core/window.py in __init__(self, obj, window, min_periods, center, win_type, axis, on, closed, **kwargs)
     78         self.win_freq = None
     79         self.axis = obj._get_axis_number(axis) if axis is not None else None
---> 80         self.validate()
     81
     82     @property

~/anaconda/lib/python3.7/site-packages/pandas/core/window.py in validate(self)
   1476
   1477         elif not is_integer(self.window):
-> 1478             raise ValueError("window must be an integer")
   1479         elif self.window < 0:
   1480             raise ValueError("window must be non-negative")

ValueError: window must be an integer

谢谢回复,我仍然不确定为什么pandas不开心,因为我没有改变源代码,但我会尝试找出原因。我没有意识到bokeh只是传递错误消息。 - Christophe Foyer
4
答案是错误的。 df.rolling 可以处理时间段,比如 '10D'(如果 new10,那么情况就是这样)。因此,错误必须有其他原因。 - tillmo
2
也许问题在于新获取的数据没有时间索引? - tillmo
1
也许你应该提交一个有用的 PR 来更新 Pandas 文档,因为目前文档明确说明 window 应该是整数类型。 - bigreddot
如果索引不是Pandas时间索引,则会发生这种情况。请参见@madhurs的答案。 - Harald Thomson

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接