我有一个包含各种事件(id)和以下结构的数据框,df按 id 分组,并按时间戳排序:
id | timestamp | A | B
1 | 02-05-2016|bla|bla
1 | 04-05-2016|bla|bla
1 | 05-05-2016|bla|bla
2 | 11-02-2015|bla|bla
2 | 14-02-2015|bla|bla
2 | 18-02-2015|bla|bla
2 | 31-03-2015|bla|bla
3 | 02-08-2016|bla|bla
3 | 07-08-2016|bla|bla
3 | 27-09-2016|bla|bla
每个 timestamp-id 组合表示事件过程中具有特定 id 的不同阶段。特定 id 的每个新记录都表示该事件ID的新阶段的开始。
我想添加一个新列持续时间,用于计算每个事件的每个阶段的持续时间(请参阅下面所需的df)。这很容易,因为我可以简单地计算同一事件id的下一阶段的时间戳与当前阶段的时间戳之间的差异,如下所示:
df['Start'] = pd.to_datetime(df['timestamp'])
df['End'] = pd.to_datetime(df['timestamp'].shift(-1))
df['Duration'] = df['End'] - df['Start']
我的问题出现在每个事件id的最后一个阶段,因为我想简单地显示NaN或短划线,因为舞台尚未完成且结束时间未知。我的解决方案只是采用下一行的时间戳并不总是正确的,因为它可能属于一个完整的不同事件。
期望的输出:
id | timestamp | A | B | Duration
1 | 02-05-2016|bla|bla| 2 days
1 | 04-05-2016|bla|bla| 1 days
1 | 05-05-2016|bla|bla| ------
2 | 11-02-2015|bla|bla| 3 days
2 | 14-02-2015|bla|bla| 4 days
2 | 18-02-2015|bla|bla| 41 days
2 | 31-03-2015|bla|bla| -------
3 | 02-08-2016|bla|bla| 5 days
3 | 07-08-2016|bla|bla| 50 days
3 | 27-09-2016|bla|bla| -------
答案 0 :(得分:2)
我认为这可以满足您的需求:
df['timestamp'] = pd.to_datetime(df['timestamp'])
df['Duration'] = df.groupby('id')['timestamp'].diff().shift(-1)
如果我理解正确:groupby('id')告诉pandas将.diff()。shift(-1)应用于每个组,就好像它是一个独立于其他行的微型DataFrame。我在这个假数据上测试了它:
import pandas as pd
import numpy as np
# Generate some fake data
df = pd.DataFrame()
df['id'] = [1]*5 + [2]*3 + [3]*4
df['timestamp'] = pd.to_datetime('2017-01-1')
duration = sorted(np.random.randint(30,size=len(df)))
df['timestamp'] += pd.to_timedelta(duration)
df['A'] = 'spam'
df['B'] = 'eggs'
但仔细检查以确保我没有犯错!
答案 1 :(得分:1)
以下是使用 Glide.with(getContext())
.using(new FirebaseImageLoader())
.load(storageReference.child(item.getImageUrl()))
.placeholder(R.drawable.category_image_not_found)
.signature(???)
.into(image);
apply
<强>输出:强>
def timediff(row):
row['timestamp'] = pd.to_datetime(row['timestamp'], format='%d-%m-%Y')
return pd.DataFrame(row['timestamp'].diff().shift(-1))
res = df.assign(duration=df.groupby('id').apply(timediff))