根据日期时间值之间的时间增量过滤数据

时间:2019-05-02 21:57:18

标签: python pandas

我正在清理熊猫中的一些数据,并试图将其归类。本质上,这是来自呼叫中心的数据。

我已经做了很多操作,并且有一个“坏”的调用类别。我想做的是将“不良”数据帧分为两个单独的数据帧:“不良”和“不太差”。

我可以从逻辑上细分这些最简单的方法是,如果多次调用该号码,则“错误”的调用仍然“不太糟糕”。但是,如果该号码仅被呼叫一次,那将是一次“糟糕的”呼叫努力。

听起来很简单。但是,问题是某些数字实际上不被多次调用。例如,两个呼叫的时间戳是8:00:20和8:00:25。从本质上讲,这是中继数据中的一个小故障(无论出于什么原因,其中可能有很多),但这肯定只是一个调用。我不希望这些电话进入“还不错”类别。

我的(相关)数据具有以下形式:

index   id1    id2     timestamp                       number
------|------|-------|-------------------------------|-------------
465     255    3644    2019-05-02 08:00:20.137000      1547856254
8736    255    3644    2019-05-02 08:00:25.145000      1547856254
62      87     912     2019-04-30 05:00:00.210000      2687892346
120     87     912     2019-04-29 11:00:00.030000      2687892346

为澄清起见,timestamp列为dtype Timestamp。

索引的前两行应仅在“坏”调用数据帧中为一行。另一方面,最后两行是“还不错”的示例,应放在该数据框中。

我该怎么办?

我认为我需要基于时间戳的逻辑掩码。

此伪代码的基本矢量化版本:

if (id1,id2,number) are the same for any number of rows:
    if the timestamps are within 20 seconds of each other:
        only keep the first row

if (id1,id2,number) are repeated:
    put in "not so bad" dataframe
else:
    put in "bad" dataframe 

2 个答案:

答案 0 :(得分:1)

uniq

生产

import pandas as pd
import numpy as np
import csv
from pandas.compat import StringIO

print(pd.__version__)

csvdata = StringIO("""index,id1,id2,timestamp,number
465,255,3644,2019-05-02 08:00:20.137000,1547856254
8736,255,3644,2019-05-02 8:00:25,1547856254
8739,255,3644,2019-05-02 9:00:10,1547856254
8740,255,3644,2019-05-02 9:00:15,1547856254
8749,255,3644,2019-05-02 9:01:10,1547856254
8750,255,3644,2019-05-02 9:00:20,1547856254
8751,255,3644,2019-05-02 9:00:21,1547856254
8752,255,3644,2019-05-02 9:00:22,1547856254
62,87,912,2019-05-02 5:00:00,2687892346
120,87,912,2019-05-02 11:00:05,2687892346
120,87,912,2019-05-02 11:00:00,2687892346
""")

# prep dataframe
df = pd.read_csv(csvdata, sep=",")
df['timestamp'] = pd.to_datetime(df['timestamp'])
df.sort_values(['id1', 'id2', 'timestamp'], inplace=True)

# get timedeltas
df['timestamp_shift'] = df.groupby(['id1', 'id2', 'number']).shift()['timestamp']
df['time_delta'] = df['timestamp'] - df['timestamp_shift']
five_seconds = np.timedelta64(5,'s')

df['bad'] = df['time_delta'] <= five_seconds

print(df)

答案 1 :(得分:0)

您可以按分钟对分组进行分组:

首先,我要放秒:

    df["timestamp"] = df["timestamp"].map(lambda x: x.replace(second=0))

如果您希望保留原始值,则将时间戳从8:00:20转换为8:00。

然后您可以应用分组依据,并保留第一个元素:

    df.groupby(['timestamp', 'id1'], as_index=False).first() 

您将第一个元素id1保留在时间戳列表中。

祝你好运!