如何使用Pandas计算销售机会各阶段停留时长的中位数
解决方案
核心逻辑为:先按销售机会ID分组、按变更时间升序排序,取每条记录的下一条变更时间作为当前阶段的结束时间,计算当前阶段的停留天数后,再按阶段分组计算中位数即可。
完整实现代码
import pandas as pd # ---------------------- 1. 数据预处理 ---------------------- # 替换为你的实际数据框名,若已经加载数据可省略这行 df = pd.read_csv("你的数据路径.csv") # 转换日期列为时间类型,注意:示例数据日期列名写为reatedDate,实际使用请和你的列名对齐 df['CreatedDate'] = pd.to_datetime(df['CreatedDate']) # 按销售机会ID、变更时间排序,保证变更顺序正确 df = df.sort_values(by=['OpportunityId', 'CreatedDate']).reset_index(drop=True) # ---------------------- 2. 计算每个阶段的停留时长 ---------------------- # 对同一个销售机会,取后一条记录的变更时间作为当前阶段的结束时间 df['next_created_date'] = df.groupby('OpportunityId')['CreatedDate'].shift(-1) # 计算停留天数,保留小数 df['duration_days'] = (df['next_created_date'] - df['CreatedDate']).dt.total_seconds() / (3600 * 24) # ---------------------- 3. 按阶段分组计算中位数 ---------------------- # 你给出的所有可选阶段列表 all_stages = [ 'Closed Won', 'Closed No Deal', 'Propose', 'Negotiate', 'Qualify', 'Closed Lost', 'Invalid', 'Identify', 'Implemented', 'Close Lost', 'Close Won', 'Close No Deal' ] # 计算各阶段停留时长中位数,补全所有可选阶段 result_df = df.groupby('OldValue')['duration_days'].median().reindex(all_stages).reset_index() # 重命名列符合输出要求 result_df.columns = ['Stage', 'Average Time'] # 转换为x days的格式,没有数据的阶段填充为0天 result_df['Average Time'] = result_df['Average Time'].fillna(0).round(1).astype(str) + ' days' # 输出结果 print(result_df)
补充说明
- 你的需求要求统计中位数,示例输出表头写的
Average Time属于笔误,如果你实际需要平均值,把代码中的median()替换为mean()即可。 - 结束类阶段(如Closed系列、Invalid等)没有后续变更记录,默认不会统计停留时长,如果你需要统计这类阶段的时长,可以在计算
next_created_date后添加一行代码:df['next_created_date'] = df['next_created_date'].fillna(pd.Timestamp.now(tz='UTC')),用当前UTC时间作为结束类阶段的结束时间。
内容的提问来源于stack exchange,提问作者Raul Gonzales
相关产品推荐
相关产品推荐

