熊猫数据框:基于列和时间范围的重复

Posted

技术标签:

【中文标题】熊猫数据框:基于列和时间范围的重复【英文标题】:pandas dataframe: duplicates based on column and time range 【发布时间】:2017-11-30 07:41:29 【问题描述】:

我有一个(非常简单的)熊猫数据框,看起来像这样:

df

    datetime             user   type   msg
0  2012-11-11 15:41:08   u1     txt    hello world
1  2012-11-11 15:41:11   u2     txt    hello world
2  2012-11-21 17:00:08   u3     txt    hello world
3  2012-11-22 18:08:35   u4     txt      hello you
4  2012-11-22 18:08:37   u5     txt      hello you

我现在想做的是获取所有时间戳在 3 秒内的重复消息。期望的输出是:

   datetime              user   type   msg
0  2012-11-11 15:41:08   u1     txt    hello world
1  2012-11-11 15:41:11   u2     txt    hello world
3  2012-11-22 18:08:35   u4     txt      hello you
4  2012-11-22 18:08:37   u5     txt      hello you

没有第三行,因为它的文本与第一行和第二行相同,但它的时间戳不是 3秒以内。

我尝试将列 datetime 和 msg 定义为 duplicate() 方法的参数,但它返回一个空数据帧,因为时间戳不相同:

mask = df.duplicated(subset=['datetime', 'msg'], keep=False)

print(df[mask])
Empty DataFrame
Columns: [datetime, user, type, msg, MD5]
Index: []

有没有一种方法可以为我的“日期时间”参数定义一个范围?为了说明,某事 喜欢:

mask = df.duplicated(subset=['datetime_between_3_seconds', 'msg'], keep=False)

我们将一如既往地为您提供任何帮助。

【问题讨论】:

【参考方案1】:

这段代码给出了预期的输出

df[(df.groupby(["msg"], as_index=False)["datetime"].diff().fillna(0).dt.seconds <= 3).reset_index(drop=True)]

我已经对数据框的“msg”列进行了分组,然后选择了该数据框的“datetime”列并使用了内置函数diff。 Diff 函数查找该列的值之间的差异。用零填充 NaT 值并仅选择那些值小于 3 秒的索引。

在使用上述代码之前,请确保您的数据框按日期时间升序排序。

【讨论】:

如果我的回答有帮助,别忘了接受。谢谢 是的,已接受,非常感谢您的帮助(对于耽搁时间深表歉意)!它可以满足我的需要。 @dliv 感谢您对答案进行投票。很高兴我能帮助你。请检查此链接到accept 答案。 现在需要将fillna(0) 替换为fillna(pd.Timedelta(seconds=0))【参考方案2】:

这段代码适用于您的示例数据,尽管您可能需要处理任何极端情况。

根据您的问题,我假设您想过滤掉第一次出现在 df 中的消息。如果您有想要保留字符串的实例,如果它在另一个阈值之后再次出现,它将不起作用。

简而言之,我编写了一个函数,它将获取您的数据框和“msg”进行过滤。它获取消息第一次出现的时间戳,并将其与它出现的所有其他时间进行比较。

然后它只选择它在第一次出现后 3 秒内出现的实例。

    import numpy as np
    import pandas as pd
    #function which will return dataframe containing messages within three seconds of the first message
    def get_info_within_3seconds(df, msg):
        df_of_msg = df[df['msg']==msg].sort_values(by = 'datetime')
        t1 = df_of_msg['datetime'].reset_index(drop = True)[0]
        datetime_deltas = [(i -t1).total_seconds() for i in df_of_msg['datetime']]
        filter_list = [i <= 3.0 for i in datetime_deltas]
        return df_of_msg[filter_list]

    msgs = df['msg'].unique()
    #apply function to each unique message and then create a new df 
    new_df = pd.concat([get_info_within_3seconds(df, i) for i in msgs])

【讨论】:

感谢您的帮助,Tkanno!您的建议也很有帮助!

以上是关于熊猫数据框:基于列和时间范围的重复的主要内容,如果未能解决你的问题,请参考以下文章

如何检测熊猫数据框在两列范围之间是不是有重复项?

删除熊猫数据框中包含特定值的列和行[重复]

如何用熊猫数据框中的范围替换列值

如何使用熊猫根据列的值范围分离数据框?

熊猫数据框使用列作为行[重复]

熊猫重置索引未生效[重复]