我有一个带有DateTime索引的pd.Series
对象。间隔不是固定的间隔时间,而是可变的。例如。
ts A
10:13:00.018 100
10:13:00.023 101
10:13:00.059 102
10:13:01.123 103
10:13:01.198 104
10:13:01.520 105
我需要计算一个区间的diff
,例如100ms
。当前diff的pandas方法仅支持固定大小的周期。
我尝试过的一些解决方案:
shift
系列,然后有所作为。问题在于熊猫的shift方法会移动索引,这使得不可能减去两个序列。例如,shift(freq='100ms')
会产生:ts A
10:13:00.118 100
10:13:00.123 101
10:13:00.159 102
10:13:01.223 103
10:13:01.298 104
10:13:01.620 105
df.rolling(window='100ms', min_periods=2).apply(lambda x: x.iloc[-1] - x.iloc[0])
此方法可以完美地工作,但有一个严重的缺点,即它非常慢(这是可以预期的,因为我们只需要窗口的两个极值,但它会提取整个窗口)。
对于上述系列,是否有一种更简便,更有效的方法来执行此diff
操作?我觉得这样的解决方案应该存在于某个地方,但是我无法在论坛上猜测或找到。
答案 0 :(得分:1)
我必须创建一个自定义函数来进行滚动总和。
from datetime import datetime
from collections import deque
import pandas as pd
def rolling_window_diff(series, time_window_in_millis):
rolling_sum = 0
dq = deque()
res_list = {}
for index, value in series.items():
while len(dq) > 0:
lindex, lval = dq[-1]
tdiff_ms = (index - lindex).total_seconds() * 1000
if tdiff_ms > time_window_in_millis:
rolling_sum -= lval
dq.pop()
else:
break
rolling_sum += value
dq.append((index, value))
res_list.append({'time': index, 'rolling_window_sum': rolling_sum})
return pd.DataFrame(res_list)
它假定pd系列中的时间戳是python-datetime格式,并且是递增的顺序(否则您可以先对其进行排序)。
答案 1 :(得分:1)
您是否正在寻找类似的东西:
import pandas as pd
import datetime
data={'ts':['10:13:00.018','10:13:00.023','10:13:00.059','10:13:01.123','10:13:01.198','10:13:01.520']
,"A":[100,101,102,103,104,105]};
df = pd.DataFrame(data)
df['ts']=pd.to_datetime(df['ts'])
df.set_index('ts',inplace=True)
print(df)
df_Date=pd.date_range(start=df.index.min(), end=(df.index.max()+ datetime.timedelta(microseconds=100000)), freq='100ms')
df=df.reindex(df_Date,method='ffill',fill_value=None)
df['diff']=df['A'].shift(-1)-df['A']
print(df)
结果:
A diff
2020-11-06 10:13:00.018 100 2.0
2020-11-06 10:13:00.118 102 0.0
2020-11-06 10:13:00.218 102 0.0
2020-11-06 10:13:00.318 102 0.0
2020-11-06 10:13:00.418 102 0.0
2020-11-06 10:13:00.518 102 0.0
2020-11-06 10:13:00.618 102 0.0
2020-11-06 10:13:00.718 102 0.0
2020-11-06 10:13:00.818 102 0.0
2020-11-06 10:13:00.918 102 0.0
2020-11-06 10:13:01.018 102 0.0
2020-11-06 10:13:01.118 102 2.0
2020-11-06 10:13:01.218 104 0.0
2020-11-06 10:13:01.318 104 0.0
2020-11-06 10:13:01.418 104 0.0
2020-11-06 10:13:01.518 104 1.0
2020-11-06 10:13:01.618 105 NaN