pandas时间序列diff()恢复为Series

0 投票
1 回答
1011 浏览
提问于 2025-04-18 12:16

我正在处理一些时间序列数据,格式如下:

1984-12-12 14:08:00
1984-12-12 14:25:00
1984-12-12 14:47:00
1984-12-12 16:37:00
1984-12-12 16:37:00
1984-12-12 16:37:00
1984-12-12 17:52:00
1984-12-12 17:52:00
1984-12-12 19:29:00

在过去的几天里,本来看起来很简单的操作(一个愉快的下午),却变得复杂而令人沮丧。

顺便说一下,这里是我的需求:

  • 计算时间序列中某些行之间的差值
  • 生成这些差值的累积和

首先,当我接触到pandas和整个 group-apply-combine 的方法时,我通常会:

  • 在数据框中创建一些分组
  • 编写一个函数,接受一个分组对象并返回一个分组对象
  • 使用lambda函数将分组传递给这个函数

我认为这是标准做法,我喜欢这样做的原因是可以隐式地连接分组、处理多个列和插入新列。(这也避免了对分组的循环,使向量化更简单)……但我觉得它在处理空分组时有些麻烦……

无论如何,为了获取时间序列的差值,我发现使用 shift() 来获取时间差时会抛出 StopIteration 错误,而使用 diff(1) 则没有错误。

不过,新的差值列(事件行之间的时间差)变成了一个序列。

time                   ev             delta

1984-12-12 14:08:00        1           NaT  
1984-12-12 14:25:00        1      00:17:00  
1984-12-12 14:47:00        1      00:22:00  
1984-12-12 16:37:00        0      01:50:00  
1984-12-12 16:37:00        1      01:50:00  
1984-12-12 16:37:00        0      01:50:00  
1984-12-12 17:52:00        0      01:15:00  
1984-12-12 17:52:00        1      01:15:00  
1984-12-12 19:29:00        1      01:37:00 

尝试将序列转换为时间序列并没有成功。由于格式问题(发现了一个很长的数字+L,不符合小时、分钟、秒的格式),这显然中止了整个尝试,而尝试捕获错误也无法解决这个问题。

    try:
        pd.to_datetime(d['delta'], format='%H:%M:%S')
    except:
        pass

另一个不断出现的错误是从时间中获取总和时的 StopIteration 错误。

gg['cumt'] = pd.rolling_apply( gg['time'], 2, np.sum )
gg['cumt'] = pd.rolling_sum(gg['time'],2).shift(1)
gg['cumt'] = gg.apply(lambda x: pd.expanding_sum(x['time'], min_periods=2) )

我相信一个简单的 cumsum 没有抛出错误,gg['cumt'] = gg['tavg'].cumsum(),但时间格式问题导致字符串转换为某个整数,然后它们被当作小数字相加。

任何帮助,无论是一般性的还是具体的,都非常感谢:

我喜欢编写一个函数并返回一个分组的简单想法。还没有深入探索 transform 函数(我觉得我无法让它工作);在函数中返回修改后的分组是否可以消除对变换/广播的需求?这是否是导致我出现 StopIteration 错误的原因?我感觉它无法处理某些分组为空的情况?

1 个回答

4

这是关于使用Pandas和Numpy这两个库的内容。Pandas是一个用来处理数据的工具,而Numpy则是用来进行数学计算的。这里提到的版本号,比如Pandas 0.12.0和Numpy 1.7.1,表示这些工具的具体版本。Python 2.7.5是使用的编程语言的版本,而Linux Mint是操作系统的名称。

import pandas as pd
import StringIO

data = '''time
1984-12-12 14:08:00
1984-12-12 14:25:00
1984-12-12 14:47:00
1984-12-12 16:37:00
1984-12-12 16:37:00
1984-12-12 16:37:00
1984-12-12 17:52:00
1984-12-12 17:52:00
1984-12-12 19:29:00'''

df = pd.read_csv(StringIO.StringIO(data))

df['time'] = pd.DatetimeIndex(df['time'])

df['delta'] = df['time'].diff()

#df['delta'] = pd.TimeSeries(df['delta']) # sorry, not needed

#df['delta'][0] = 0 # to remove NaT 

# better method to remove NaT - thanks to Jeff
df['delta'] = df['delta'].fillna(0) 

df['cumsum'] = df['delta'].cumsum()

print df

结果

                   time      delta     cumsum
0   1984-12-12 14:08:00   00:00:00   00:00:00
1   1984-12-12 14:25:00   00:17:00   00:17:00
2   1984-12-12 14:47:00   00:22:00   00:39:00
3   1984-12-12 16:37:00   01:50:00   02:29:00
4   1984-12-12 16:37:00   00:00:00   02:29:00
5   1984-12-12 16:37:00   00:00:00   02:29:00
6   1984-12-12 17:52:00   01:15:00   03:44:00
7   1984-12-12 17:52:00   00:00:00   03:44:00
8   1984-12-12 19:29:00   01:37:00   05:21:00

撰写回答