You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Pandas分组复杂滚动计算优化:通话时长异常检测需求

Pandas通话日志高效检测被叫号码时长限制方案

核心优化思路

原循环分组写法效率低下的根源是手动迭代每个分组、生成偏移列会产生大量中间对象,无法利用Pandas底层的矢量化优化。改用groupby结合滚动窗口(rolling)函数,可直接完成全矢量化计算,性能提升显著。

具体实现步骤

1. 预排序数据

确保每个被叫号码的通话记录按时间戳升序排列,保证"最近5次"的逻辑正确性:

# 按被叫号码分组,组内按时间戳升序排序
df_sorted = df.sort_values(['dest_number', 'unix_timestamp'])

2. 滚动计算统计量

针对每个被叫号码的分组,用滚动窗口直接计算最近5次通话的均值、标准差,并生成ratio_pre:

# 计算最近5条记录的滚动均值与标准差(仅保留至少5条记录的窗口)
rolling_stats = df_sorted.groupby('dest_number')['real_duration'].rolling(5, min_periods=5).agg(['mean', 'std'])

# 计算比值,替换均值为0的情况避免除零错误
rolling_stats['ratio_pre'] = rolling_stats['std'] / rolling_stats['mean'].replace(0, float('nan'))

3. 生成目标结果表

提取每个被叫号码的最后一次ratio_pre,整理为以dest_number为索引的结果:

# 重置索引后取每个分组的最后一条记录,重命名列名
result = rolling_stats.reset_index()\
                      .groupby('dest_number').last()[['ratio_pre']]\
                      .rename(columns={'ratio_pre': 'last_ratio_pre'})

关键优化点说明

  • 替代手动偏移列:用rolling(5)直接获取滑动窗口,无需生成5个偏移列,减少内存占用和计算步骤。
  • 全矢量化执行:groupby+rolling基于Pandas的C扩展实现,比Python循环效率高10~100倍,数据量越大优势越明显。
  • 边界情况处理:min_periods=5确保仅对通话次数≥5的号码计算统计值;replace(0, float('nan'))规避均值为0时的除零异常。

额外性能优化建议

如果数据量极大,可预先过滤通话次数不足5次的号码,减少分组计算量:

# 筛选出至少有5次通话的被叫号码
valid_dests = df['dest_number'].value_counts()[lambda x: x >=5].index
df_filtered = df[df['dest_number'].isin(valid_dests)]
# 后续排序、滚动计算基于过滤后的数据执行

内容的提问来源于stack exchange,提问作者user194145

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 16:48:18