首页 > 解决方案 > 从数据框获取项目 A 的第一个订单与前一个订单之间的天数,前一个订单可以是项目 A 或不同的项目

问题描述

我有一个数据框,包括所有客户一年内的所有订单。我想知道两个订单之间的平均天数:第二个订单需要是一个特定的项目。我称它为 A 项。此项目必须是客户第一次或第二次订购。第一个订单可以是项目 A 或任何其他项目。第一个订单并不意味着客户是第一次订购。这只是之前的命令。

下面是初始表的示例。它以粗体显示我感兴趣的行。为了获得天数的差异,我需要找到一种方法以粗体显示数据。

我尝试了不同的东西,比如 groupby().first() 或 nth() 但它们都没有完全符合我的要求。

顾客 日期 项目A B项
客户 1 2020/03/01 0 1
客户 2 2020/03/02 1 0
客户 3 2020/03/03 0 1
客户 3 2020/03/04 1 0
客户 3 2020/03/05 1 0
客户 4 2020/03/06 0 1
客户 4 2020/03/07 0 1
客户 4 2020/03/08 0 1
客户 4 2020/03/09 1 0
客户 4 2020/03/10 1 0
客户 4 2020/03/11 1 0
客户5 2020/03/14 1 0
客户5 2020/03/15 1 0

*编辑 :

预期输出表:

有3个客户,每个人相差1天,所以平均为(1+1+1)/3 = 1天

顾客 日期 项目A B项
客户 3 2020/03/03 0 1
客户 3 2020/03/04 1 0
客户 4 2020/03/08 0 1
客户 4 2020/03/09 1 0
客户5 2020/03/14 1 0
客户5 2020/03/15 1 0

标签: pythonpandasdataframepandas-groupby

解决方案


首先,让我们确保为每个客户订购date了和 :Timestamp

df = df.assign(date=pd.to_datetime(df['date'])).sort_values(['customer', 'date'])

然后,据我了解所需的逻辑,它是:

  • 考虑的主要顺序是,对于每个客户,包含'item A'除第一个之外的所有客户订单中的第一个订单,
  • 时间差是该订单和前一个订单之间的时间差。

表达该逻辑的一种方法是:

gb = df.groupby('customer')
a = gb['item A'].cumsum()
n = gb.cumcount()
mask = ((a == 1) & (n > 0)) | ((a == 2) & (n == 1))

然后,您可以选择该“考虑顺序”及其前一个:

out = df.loc[mask | mask.shift(-1)]

这给出了 OP 想要获得的数据框:

>>> out
   customer       date  item A  item B
2    cust 3 2020-03-03       0       1
3    cust 3 2020-03-04       1       0
7    cust 4 2020-03-08       0       1
8    cust 4 2020-03-09       1       0
12   cust 5 2020-03-13       0       0
13   cust 5 2020-03-14       1       0

或者,直接获取两个订单之间的平均时间差:

avg_dt = df['date'].diff()[mask].mean()
# Timedelta('1 days 00:00:00')

推荐阅读