簡體   English   中英

Python Pandas 計算事件發生之間的時間增量

[英]Python Pandas Calculating timedelta between event occurrences

我有一個 Pandas (0.14.1) 數據框,它有一個datetime和一個event列,如下所示:

import pandas as pd
from datetime import datetime
from datetime import timedelta
def perdelta(start, end, delta):
   curr = start
   while curr < end:
     yield curr;  
     curr += delta;
events = [np.nan] * 20; events[5]=20; events[12]=3; events[15]=10;
n = len(events)
signal = [i/10.0 for i in range(n)] + np.random.randn(n)
df = pd.DataFrame( { 'level1': signal,
                     'event' : events, 
                     'datetime': [r for r in perdelta(datetime.now(),  datetime.now() + timedelta(minutes=10) , timedelta(seconds=30))]}, 
                      index=range(n))

df.head(7)
                    datetime  event    level1
0 2016-07-14 10:44:47.035000    NaN  0.158594
1 2016-07-14 10:45:17.035000    NaN  0.282749
2 2016-07-14 10:45:47.035000    NaN  0.448012
3 2016-07-14 10:46:17.035000    NaN  0.590702
4 2016-07-14 10:46:47.035000    NaN -0.346073
5 2016-07-14 10:47:17.035000     20  0.072986
6 2016-07-14 10:47:47.035000    NaN  1.493900

我想包含一個t_since_last_event列,用於計算自上次事件發生以來每個時間步的增量時間。 生成的 df 應如下所示:

df
                     datetime  event    level1  t_since_last_event
0  2016-07-14 10:44:47.035000    NaN  0.158594                  0
1  2016-07-14 10:45:17.035000    NaN  0.282749                 30
2  2016-07-14 10:45:47.035000    NaN  0.448012                 60
3  2016-07-14 10:46:17.035000    NaN  0.590702                 90
4  2016-07-14 10:46:47.035000    NaN -0.346073                120
5  2016-07-14 10:47:17.035000     20  0.072986                  0
6  2016-07-14 10:47:47.035000    NaN  1.493900                 30
7  2016-07-14 10:48:17.035000    NaN -0.143081                 60
8  2016-07-14 10:48:47.035000    NaN  0.173715                 90
9  2016-07-14 10:49:17.035000    NaN  1.232040                120
10 2016-07-14 10:49:47.035000    NaN  3.497438                150
11 2016-07-14 10:50:17.035000    NaN  0.956582                180
12 2016-07-14 10:50:47.035000      3  2.976383                  0
13 2016-07-14 10:51:17.035000    NaN  0.599698                 30
14 2016-07-14 10:51:47.035000    NaN  2.538005                 60
15 2016-07-14 10:52:17.035000     10  1.362104                  0
16 2016-07-14 10:52:47.035000    NaN  2.224680                 30
17 2016-07-14 10:53:17.035000    NaN  3.221037                 60
18 2016-07-14 10:53:47.035000    NaN  1.869479                 90
19 2016-07-14 10:54:17.035000    NaN  1.447430                120

在 Pandas 中是否有一種聰明的方法來做到這一點? 它涉及水平分組(按事件發生)和垂直計數,因此解決方案對我來說不太明顯。 我在下面發布了我的傳統解決方案。

矢量化在這里應該很簡單:

  • 添加另一列將保存上次事件時間
  • 如果event不是 NaN,則在此列中設置事件時間,否則為 NaN
  • 使用方法ffill填充 NaN 值
  • datetime列中減去。

這應該適用於熊貓 0.14.1:

mask = df['event'].notnull()
df['last_event_time'] = np.NaN
df.loc[mask, 'last_event_time'] = df.loc[mask, 'datetime']
df['last_event_time'] = df['last_event_time'].fillna(method='ffill')
df['t_since_last_event'] = df['datetime'] - df['last_event_time']

您可能還希望在開始時將event的第一個元素設置為零; 或者, mask[0] = True

這是我無趣的解決方案。 我懷疑應該有一個更快的 Pandas 解決方案。 垂直和水平依賴的存在使得使用apply()groupby()等更難處理。

last_trade_time = df.iloc[0]['datetime']
t=[np.nan] * len(df)
for i, row in df.iterrows():
    if np.isnan(row['event']):
        t[i] = row['datetime'] - last_trade_time
    else:
        t[i] = 0
        last_trade_time = row['datetime']
df['t_since_last_event'] = t

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM