我的数据框有四列:P_Id,Prev_State,Current_State,Timestamp。
随着过程经历多个状态,用户可能对所有状态都具有相同的时间戳。我希望在进程从1状态转换为另一状态时为每个数据点添加一个时间戳记值(1 s)。
通过比较Prev_State和Current_State并将其匹配,该数据点的相应时间戳通过加1 s来修改。但是,如果时间戳记值与先前的数据点不同,那么我想保留原始时间戳记。
注意:我的时间戳记值间隔为30分钟。
P_Id Prev_State Current_State Timestamp
001 None Initial 2019-02-13 18:00:00
001 Ready Loading 2019-02-13 18:00:00
001 Initial Ready 2019-02-13 18:00:00
001 Loading Executing 2019-02-13 18:30:00
001 Executing Evaluating 2019-02-13 18:30:00
001 Evaluating Terminating 2019-02-13 18:30:00
预期输出:
P_Id Prev_State Current_State Timestamp
001 None Initial 2019-02-13 18:00:00
001 Ready Loading 2019-02-13 18:00:02
001 Initial Ready 2019-02-13 18:00:01
001 Loading Executing 2019-02-13 18:30:00
001 Executing Evaluating 2019-02-13 18:30:01
001 Evaluating Terminating 2019-02-13 18:30:02
我是python的新手。任何帮助将不胜感激!
答案 0 :(得分:3)
可以通过一些有趣的networkx
来完成。我们创建一个有向图,然后形成最长的路径。 (理想情况下,您的DataFrame总是通过单个路径连接,如示例中所示)。然后,我们使用有序的分类对它进行排序,以便进行排序。最后,为每个新条目添加1,然后返回系列。
import networkx as nx
import pandas as pd
import numpy as np
def add_second(gp):
# Get Path
G = nx.from_pandas_edgelist(gp, source='Prev_State', target='Current_State',
create_using=nx.DiGraph())
order = nx.dag_longest_path(G)[:-1]
# Order
gp['Prev_State'] = pd.Categorical(gp.Prev_State, ordered=True, categories=order)
gp = gp.sort_values('Prev_State')
# Add 1s
s = gp.Timestamp + pd.to_timedelta(range(len(gp)), unit='s')
return s
df['new_time'] = df.groupby(['P_Id', 'Timestamp'], group_keys=False).apply(add_second)
P_Id Prev_State Current_State Timestamp new_time
0 1 None Initial 2019-02-13 18:00:00 2019-02-13 18:00:00
1 1 Ready Loading 2019-02-13 18:00:00 2019-02-13 18:00:02
2 1 Initial Ready 2019-02-13 18:00:00 2019-02-13 18:00:01
3 1 Loading Executing 2019-02-13 18:30:00 2019-02-13 18:30:00
4 1 Executing Evaluating 2019-02-13 18:30:00 2019-02-13 18:30:01
5 1 Evaluating Terminating 2019-02-13 18:30:00 2019-02-13 18:30:02