使用Pandas进行大数据集的基于组的时差分析

4
我有一个大型数据集(大约25万行),其中包含属性ID号码和调查响应日期时间。我正在尝试构建一种基本的欺诈检测方法,其中考虑的因素之一是每个属性/商店的不同调查之间的响应时间。如果某个位置的任何调查之间的时间间隔少于10分钟,我希望在名为“close_response”的列下将其标记为TRUE。
我在一个函数中嵌套了for循环,该函数应用于每个组,实现了我想要的效果,但在应用于非常大的数据集时,计算成本高且耗时。
import pandas as pd
from datetime import timedelta

# Sample DataFrame
data = {'property_id': [1, 1, 1, 2, 2, 3, 3],
        'response_datetime': ['2023-10-19 08:00:00', '2023-10-19 08:05:00', '2023-10-19 08:25:00', '2023-10-19 09:00:00', '2023-10-19 09:15:00', '2023-10-19 10:00:00', '2023-10-19 11:00:00']}
df = pd.DataFrame(data)
df['response_datetime'] = pd.to_datetime(df['response_datetime'])

def mark_close_responses(group):
    group['close_response'] = False
    for i in range(len(group)):
        for j in range(i+1, len(group)):
            time_diff = group.iloc[j]['response_datetime'] - group.iloc[i]['response_datetime']
            if time_diff <= timedelta(minutes=10):
                group.at[i, 'close_response'] = True
                group.at[j, 'close_response'] = True
    return group

df = df.groupby('property_id').apply(mark_close_responses)

在每个组内,您只想比较连续的时间戳并检查它们是否在一个阈值范围内,是这样理解的吗?为什么您需要一个嵌套循环来实现这个功能? - undefined
2个回答

3
使用diff计算相邻行之间的差异,获取差异小于或等于10分钟的行,使用条件语句获取每个组的准确位置,向后填充并将结果赋值回原始数据框。
difference=df.groupby('property_id').response_datetime.diff()
out = difference.le(pd.Timedelta(minutes=10))
out = difference.where(difference.isna(), out).bfill()
df.assign(close_response=out)
   property_id   response_datetime  close_response
0            1 2023-10-19 08:00:00            True
1            1 2023-10-19 08:05:00            True
2            1 2023-10-19 08:25:00           False
3            2 2023-10-19 09:00:00           False
4            2 2023-10-19 09:15:00           False
5            3 2023-10-19 10:00:00           False
6            3 2023-10-19 11:00:00           False

当满足条件的第一行不是数据框的第一行时,它就不起作用。如果在2023-10-19 08:00:00之前添加另一行,比如2023-10-18 08:00:00,那么2023-10-19 08:00:00就不会被应用True。我之前在自己的代码中也遇到了类似的问题,使用diff时无法解决。 - undefined
请提供一个更新的示例,并附上预期的输出结果。 - undefined

1
再加一段代码来实现结果
import pandas as pd

df['response_datetime'] = pd.to_datetime(df['response_datetime'])

def mark_close_responses(group):
    time_diff = group['response_datetime'].diff().le(pd.Timedelta(minutes=10))
    group['close_response'] = time_diff | time_diff.shift(-1, fill_value=False)
    return group

df = df.groupby('property_id').apply(mark_close_responses).reset_index(drop=True)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接