我正在清理熊猫中的一些数据,并试图将其归类。本质上,这是来自呼叫中心的数据。
我已经做了很多操作,并且有一个“坏”的调用类别。我想做的是将“不良”数据帧分为两个单独的数据帧:“不良”和“不太差”。
我可以从逻辑上细分这些最简单的方法是,如果多次调用该号码,则“错误”的调用仍然“不太糟糕”。但是,如果该号码仅被呼叫一次,那将是一次“糟糕的”呼叫努力。
听起来很简单。但是,问题是某些数字实际上不被多次调用。例如,两个呼叫的时间戳是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
答案 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保留在时间戳列表中。
祝你好运!