如何从 Pandas 中的 DatetimeIndex 获取滚动窗口内的持续时间

Posted

技术标签:

【中文标题】如何从 Pandas 中的 DatetimeIndex 获取滚动窗口内的持续时间【英文标题】:How to get the duration inside the rolling window from he DatetimeIndex in Pandas 【发布时间】:2018-02-19 10:44:54 【问题描述】:

我正在尝试计算此数据在每个滑动窗口内的持续时间:

                                ID  
    DATE            
    2017-05-17 15:49:51         2   
    2017-05-17 15:49:52         5   
    2017-05-17 15:49:55         2   
    2017-05-17 15:49:56         3   
    2017-05-17 15:49:58         5
    2017-05-17 15:49:59         5

在此示例中,DATE 是索引,我试图获取大小为 3 的滚动窗口内的持续时间,它们相互重叠。答案应该是这样的:

                                ID      duration    
    DATE            
    2017-05-17 15:49:51         2        4  
    2017-05-17 15:49:52         5        4  
    2017-05-17 15:49:55         2        3  
    2017-05-17 15:49:56         3        3  
    2017-05-17 15:49:58         5        NaN
    2017-05-17 15:49:59         5        NaN

我试过了:

df['duration'] = df.rolling(window=3).apply(df.index.max()-df.index.min())

但是我收到了这个错误:

TypeError: 'DatetimeIndex' object is not callable

【问题讨论】:

试试df['duration'] = df.rolling(window=3).apply(lambda x: x.index.max()-x.index.min()) 我之前做过,我收到了这个错误AttributeError: 'numpy.ndarray' object has no attribute 'index' 相关:***.com/questions/37486502/… 我也试试这个df['duration'] = df.rolling(5).apply(lambda x: pd.to_datetime(x.index.max()) - pd.to_datetime(x.index.min()))得到同样的错误AttributeError: 'numpy.ndarray' object has no attribute 'index' 正如链接问题所解释的那样,rolling 适用于 numpy 数组,而不是数据框,因此您无法访问其中的所有 pandas 功能。您必须找到基于数组索引的解决方法。 【参考方案1】:
def timediff(time_window: pd.Series) -> float:
    duration = time_window.index.max() - time_window.index.min() 
    return duration.total_seconds()

df['duration'] = np.nan
df['duration'] = df.duration.rolling(window=3).apply(func=timediff, raw=False)

我刚刚偶然发现了这个问题,并想提供一个使用滚动窗口方法的解决方案: 使用raw=False(默认)为函数提供一个系列,因此您可以使用index.max() - index.min()index[-1] - index[0] 唯一的问题是您需要返回一个数字而不是 timedelta 对象。

【讨论】:

【参考方案2】:
df.reset_index(inplace=True)    
df['PREVIOUS_TIME']= df.DATE.shift(-2)
df['duration']=(df.PREVIOUS_TIME-df.DATE)/np.timedelta64(1,'s')
df.drop('PREVIOUS_TIME',axis=1,inplace=True)
df.set_index('DATE',inplace=True)

假设 'DATE' 是一个日期时间。

【讨论】:

DATE 是索引所以我不能打电话给df.DATE.shift(-3) df.DATE.reset_index(inplace=True);之后 df.set_index('DATE',inplace=True) 它没有给我我正在寻找的答案。如果你看我的例子,时间滑动窗口会相互重叠:In Window-1: 15:49:55 - 15:49:51 = 4In window-2: 15:49:56 - 15:49:52 = 4In window-3: 15:49:58 - 15:49:55 = 3等等。 啊,好的,那你应该用 shift -2 而不是 shift -3 非常感谢,我花了太多时间来解决这个问题

以上是关于如何从 Pandas 中的 DatetimeIndex 获取滚动窗口内的持续时间的主要内容,如果未能解决你的问题,请参考以下文章

如何从 Pandas 中的 DatetimeIndex 获取滚动窗口内的持续时间

如何从 Pandas 数据框列中的日期时间减去 3 小时?

如何从python中的pandas数据框中的列中提取关键字(字符串)

Pandas:如何将数据框列中的“时间戳”值从对象/字符串转换为时间戳?

如何从 pandas 数据框中的大型每日 JSON 数据集计算平均月值?

如何使用 Pandas 从 DataFrame 或 np.array 中的列条目创建字典