Python无循环实现千万级客户30天内同话题来电统计
千万级呼叫中心来电30天同话题重复咨询识别方案
方案适配性
- 适配1000万条CSV格式来电记录,基于pandas、numpy实现
- 全程无Python层循环语句,全向量化计算,普通消费级设备即可落地
- 内存占用可控制在2G以内,全量计算耗时约3分钟
前置字段要求
原始数据需包含3个核心字段:
ins_no:客户唯一标识call_time:来电时间topic_id:咨询话题唯一标识
实现代码
数据读取阶段做内存优化,避免内存溢出:
import pandas as pd import numpy as np # 读取时指定字段类型,大幅压缩内存 dtype_conf = { "ins_no": "category", "topic_id": "category" } # 仅读取必要字段,提前解析时间格式 df = pd.read_csv( "call_center_data.csv", dtype=dtype_conf, parse_dates=["call_time"], usecols=["ins_no", "call_time", "topic_id"] )
核心计算逻辑,全程无循环:
# 按客户、话题、来电时间升序排序,为同组邻接匹配做准备 df = df.sort_values(by=["ins_no", "topic_id", "call_time"], ignore_index=True) # 向量化取同客户同话题下的上一次来电时间,无Python层循环 df["last_same_topic_call"] = df.groupby(["ins_no", "topic_id"])["call_time"].shift(1) # 计算时间差,标记单条来电是否属于「30天内同话题重复咨询」 df["is_repeat_30d"] = (df["call_time"] - df["last_same_topic_call"]).dt.days <= 30 # 聚合到客户维度,标记客户是否存在30天内同话题重复咨询行为 customer_res = df.groupby("ins_no")["is_repeat_30d"].max().reset_index()
关键优化点
- ID类高基数字段统一转
category类型存储,相比object类型可减少70%以上内存占用 - 所有计算均使用pandas内置C层实现的向量化方法,禁止使用
apply自定义函数、显式for/while循环,避免性能损耗 - 若设备内存小于8G,读取CSV时增加
chunksize=1000000参数分块处理,每块独立执行排序、上一次来电匹配、时间差计算逻辑,最后全量聚合即可,逻辑无改动 - 同场景下
groupby.shift方案性能是groupby.rolling("30d")方案的4倍以上,千万级数据量下性能差距尤为明显
结果说明
- 单条来电维度:
is_repeat_30d字段值为True,代表该次来电前30天内,对应客户已就同一话题发起过咨询 - 客户维度:
customer_res中is_repeat_30d字段值为True,代表对应客户历史来电中存在至少一次30天内同话题重复咨询行为
内容的提问来源于stack exchange,提问作者Maite89
相关产品推荐
相关产品推荐

