【问题标题】:summary of converted and churned customers from time series dataframe从时间序列数据框中转换和流失客户的摘要
【发布时间】:2020-09-30 03:01:42
【问题描述】:

我有类似于下面的数据框,我想围绕客户的行为创建一些摘要统计数据

pd.DataFrame([
['id1','23/5/2019','not_emailed']
,['id1','24/5/2019','not_emailed']
,['id1','25/5/2019','emailed']
,['id1','26/5/2019','emailed']
,['id1','27/5/2019','emailed']
,['id1','28/5/2019','emailed']
,['id1','29/5/2019','emailed']
,['id1','30/5/2019','emailed']
,['id1','31/5/2019','emailed']
,['id1','1/6/2019','emailed']
,['id1','2/6/2019','emailed']

,['id2','23/5/2019','not_emailed']
,['id2','24/5/2019','not_emailed']
,['id2','25/5/2019','emailed']
,['id2','26/5/2019','emailed']
,['id2','27/5/2019','emailed']

,['id3','29/5/2019','not_emailed']
,['id3','30/5/2019','emailed']
,['id3','31/5/2019','emailed']
,['id3','1/6/2019','emailed']
,['id3','2/6/2019','emailed']

 ,['id4','29/5/2019','not_emailed']
 ,['id4','30/5/2019','emailed']
 ,['id4','31/5/2019','emailed']
 ,['id4','1/6/2019','emailed']
 ,['id4','2/6/2019','emailed']    
,['id4','2/7/2019','emailed']    
,['id4','3/7/2019','emailed']
,['id4','4/7/2019','emailed'] 
 ],columns=['id','date','status'])

在这个数据集中可以观察到的主要场景有:

id1 于 25 日通过电子邮件发送但未转换

id2 于 27 日通过电子邮件发送,并于 28 日转换,因为我们没有看到该 id 的更多日志

id3 于 30 日通过电子邮件发送并在 3 日转换,因为我们没有看到该 id 的更多日志

id4 在 30 日通过电子邮件发送并在 3 日转换,但在 2 日再次流失

我想每天获得该信息的摘要

通过电子邮件发送了多少,转化了多少,之前已经转化的流失了多少

期望的潜在输出可能是:

        pd.DataFrame([
        ['29/5/2019',10,3,1] ,
        ['30/5/2019',10,2,1] 
        ],columns=['date','emailed_total','converted_total','churned_total']
        )

不是上面的数字是随机的,不反映第一个共享数据集的统计数据

到目前为止我的方法:

1) 部分解决问题: 查找电子邮件的第一天 计算自第一次以来经过的天数 按经过的天数分组并汇总 有效,但不适用于流失客户

2) 循环日期 过滤通过电子邮件发送的唯一 ID 循环遍历未来的日期并计算集合之间的差异 做的工作,但不是很干净和pythonic

【问题讨论】:

  • 在所需的输出数据框中有'emailed_total'、'converted_total'和'churned_total'。需要分别明确列的聚合条件。呈现的数据中只有两种状态。
  • 三者中哪一个不清楚应该如何聚合? “emailed_total”:当天每个人都通过电子邮件发送,“converted_total”:之前通过电子邮件发送但当天缺席的每个人,“churned_total”:之前通过电子邮件发送,在前一天转换但他们又回到了列表中。
  • 'churned_total' 返回列表,这是什么意思?你能详细说明一下总名和地位之间的关系吗?我不是母语人士。
  • 对,所以如果客户流失了,它每天都会出现在我的数据中。如果客户已经转换,它将停止出现在数据上,但如果他再次流失,它将开始重新出现在数据集上。在 id4 的示例场景中:客户在 2020 年 5 月 30 日通过电子邮件发送并在 2020 年 3 月 6 日转换,因为在我的数据中没有记录 id4 的该日期。它们在 2020 年 2 月 7 日重新出现,因为它们再次搅动。
  • 'churned_total' 的状态是什么?如果他们没有地位,你就不能算他们。您的描述是指取消的天数吗?我越来越不确定了。

标签: pandas time-series pandas-groupby analytics summary


【解决方案1】:

按照我目前的理解,我已经编写了代码来回答您的问题。但正如我评论的那样,关于搅拌的状态已经被弄乱了,所以只有两个不同的总数。它没有完成。列名也不是你想要的名字。

df['date'] = pd.to_datetime(df['date'], format='%d/%m/%Y')
df2 = df.groupby(['date','status']).agg('count').unstack().fillna(0)
df2.columns = df2.columns.droplevel()
df2 = df2.rename_axis(columns=None).reset_index()
df2.sort_index(ascending=True, inplace=True)

df
    date    emailed     not_emailed
0   2019-05-23  0.0     2.0
1   2019-05-24  0.0     2.0
2   2019-05-25  2.0     0.0
3   2019-05-26  2.0     0.0
4   2019-05-27  2.0     0.0
5   2019-05-28  1.0     0.0
6   2019-05-29  1.0     2.0
7   2019-05-30  3.0     0.0
8   2019-05-31  3.0     0.0
9   2019-06-01  3.0     0.0
10  2019-06-02  3.0     0.0
11  2019-07-02  1.0     0.0
12  2019-07-03  1.0     0.0
13  2019-07-04  1.0     0.0

【讨论】:

    【解决方案2】:

    根据您的要求,我对您的数据、转换时间和未转换的 id 时间做了一些了解。 希望对你有帮助

    df['date']=pd.to_datetime(df['date'],infer_datetime_format=True)
    df.sort_values(by='date',inplace=True)
    dates=df['date'].unique()
    ids=df['id'].unique()
    df=df.set_index(['id','date'])
    
    out=pd.DataFrame(index=dates)
    for i, new_df in df.groupby(level=0):
        new_df=new_df.droplevel(0)
        new_df=new_df.rename(columns={'status':i})
        out=out.merge(new_df, how='outer', left_index=True, right_index=True)
        
    
    not_converted=out[out.columns[out.iloc[-1,:]=='emailed']]
    converted=out[out.columns[out.iloc[-1,:].isnull()]]
    
    start_mailing_date_NC=(not_converted=='emailed').cumsum().idxmin() #not converted id metrics
    
    delta_NC=(dates[-1]-start_mailing_date_NC) #dates[-1] could be changed to actual date
    print("Days from first mail unconverted by id: ")
    print(delta_NC.to_string())
    print(' Mean Days not converted: %s'%(delta_NC.mean()))
    print( '\n')
    
    
    
    start_mailing_date=(converted=='emailed').cumsum().idxmin() #converted id metrics
    conversion_mailing_date=(converted=='emailed').cumsum().idxmax()#converted id metrics
    delta=(conversion_mailing_date-start_mailing_date)
    print("Days to conversion by id: ")
    print(delta.to_string())
    print(' Mean Days to conversion: %s'%(delta.mean()))
    

    输出:

    Days from first mail unconverted by id: 
    id4   42 days
     Mean Days not converted: 42 days 00:00:00
    
    
    Days to conversion by id: 
    id1   10 days
    id2    4 days
    id3   10 days
     Mean Days to conversion: 8 days 00:00:00
    

    【讨论】:

      猜你喜欢
      • 2018-09-12
      • 1970-01-01
      • 1970-01-01
      • 2021-04-19
      • 1970-01-01
      • 2018-10-23
      • 1970-01-01
      • 2020-06-07
      • 2021-05-02
      相关资源
      最近更新 更多