一个想法是接受 1 月至 11 月的所有订单,并有一个“reccurr”列,根据该客户是否在下个月订购,它会为您提供真/假。然后,您可以使用包含真/假计数/总和的每月 groupby 并添加一个给出比率的列。
编辑:在此之前您可能需要转换日期:
df.Date = pd.to_datetime(df.Date)
然后:
df['month'] = df['Date'].apply(lambda x: x.month) #this is for simplicity's sake, not hard to extend to MMYYYY
df1 = df[df.month != 12].copy() #now we select everything but Nov
df1 = df1[df1.First_order == 1].copy() #and filter out non-first orders
df1['recurr'] = df1.apply(lambda x: True if len(df[(df.month == x.month + 1)&(df.Name == x.Name)])>0 else False, axis=1) #Now we fill a column with True if it finds an order from the same person next month
df2 = df1[['month','Name','recurr']].groupby('month').agg({'Name':'count','recurr':'sum'})
此时,对于每个月,“名称”列都有第一个订单的数量,“重复”列有下个月再次订购的数量。一个简单的额外列为您提供百分比:
df2['percentage_of_recurring_customer'] = (df2.recurr/df2.Name)*100
编辑:对于任意数量的日期,这是一个笨拙的解决方案。选择一个开始日期并将当年的 1 月用作第 1 个月,然后按顺序编号之后的所有月份。
df.Date = pd.to_datetime(df.Date)
start_year = df.Date.min().year
def get_month_num(date):
return (date.year-start_year)*12+date.month
现在我们有了转换日期的函数,代码稍作改动:
df['month'] = df['Date'].apply(lambda x: get_month_num(x))
df1 = df[df.First_order == 1].copy()
df1['recurr'] = df1.apply(lambda x: True if len(df[(df.month == x.month + 1)&(df.Name == x.Name)])>0 else False, axis=1)
df2 = df1[['month','Name','recurr']].groupby('month').agg({'Name':'count','recurr':'sum'})
最后,您可以创建一个函数将您的月份数字还原为日期:
def restore_month(month_num):
year = int(month_num/12)+start_year #int rounds down so we can do this.
month = month_num%12 #modulo gives us month
return pd.Timestamp(str(year)+'-'+str(month)+'-1') #This returns the first of that month
df3 = df2.reset_index().copy() #removing month from index so we can change it.
df3['month_date'] = df3['month'].apply(lambda x: restore_month(x))