我有两个熊猫数据框(这里只有前几行):
event_timestamp message_number an_robot
2015-04-15 12:09:39 10125 robot_7
2015-04-15 12:09:41 10053 robot_4
2015-04-15 12:09:44 10156_added robot_7
2015-04-15 12:09:47 20205 robot_108
2015-04-15 12:09:51 10010 robot_38
2015-04-15 12:09:54 10012 robot_65
2015-04-15 12:09:59 10011 robot_39
和(仅前两行,序列行中项目的最大长度为此类字符串值的5):
sequence support
10053,10156,20205 0.94783
10010,10012 0.93322
我想对第二个数据帧中出现的序列过滤第一个数据帧。我有此代码一个接一个:
def find_drops(seq, df):
if seq:
m = np.logical_and.reduce([df.message_number.shift(-i).eq(seq[i]) for i in range(len(seq))])
if len(seq) == 1:
return pd.Series(m, index=df.index)
else:
return pd.Series(m, index=df.index).replace({False: np.NaN}).ffill(limit=len(seq)-1).fillna(False)
else:
return pd.Series(False, index=df.index)
如果我运行df1[~find_drops([10053,10156_added,20205], df1)]
,则结果正确无误,如下所示:
event_timestamp message_number an_robot
2015-04-15 12:09:39 10125 robot_7
2015-04-15 12:09:51 10010 robot_38
2015-04-15 12:09:54 10012 robot_65
2015-04-15 12:09:59 10011 robot_39
但是,过滤非常苛刻。我想在数据集中保留1行,以告知该序列确实发生了(我的总体目标是事件日志摘要)。拥有这样的东西真是太好了,在这里我们将message_number和an_robot值合并为一行,并且所有图像均在出现该序列的第一个时间戳时发生:
event_timestamp message_number an_robot
2015-04-15 12:09:39 10125 robot_7
2015-04-15 12:09:41 10053,10156_added,20205 robot_4,robot_7,robot_108
2015-04-15 12:09:51 10010,10012 robot_38,robot_65
2015-04-15 12:09:59 10011 robot_39
或者每当新序列弹出时,我们就可以从0开始计数到len(df2)(因为我总是可以按索引查找df2中0代表什么):
event_timestamp message_number an_robot
2015-04-15 12:09:39 10125 robot_7
2015-04-15 12:09:41 0 robot_4,robot_7,robot_108
2015-04-15 12:09:51 1 robot_38,robot_65
2015-04-15 12:09:59 10011 robot_39
我真的不知道如何更改我的功能来做到这一点。另外,如果我可以只键入df(find_drops(df1.iloc[0,0], df)]
,那将是很棒的,因为我随后可以创建一个循环来执行df1.iloc[0,0], df1.iloc[1,0]
等操作,因为我在df2中有大约500个这样的序列。对于我已经编写的功能,我也没有找到实现此目的的方法。
我希望任何人都知道我在想什么!