我最近在pandas做了一个关于一年交易的RFM分析,但现在我想给每个客户每个月的RFM评分,我的数据框架如下所示:
txn_id | customer_id | date | total
1 | 2 | 2016-1-2 | 30
2 | 5 | 2016-1-3 | 21
3 | 2 | 2016-1-4 | 9
4 | 3 | 2016-3-2 | 10
5 | 2 | 2016-3-1 | 10要计算一整年的RFM分数,我使用
now = dt.datetime(2016,12,31)
df.groupby('customer_id').agg({'date': lambda x: (now - x.max()).days,
'txn_id': lambda x: len(x),
'total : lambda x : sum(x)})
rfm = df['date'] = df['date'].astype(int)
rfm.rename(columns={'date': 'recency',
'txn_id': 'frequency',
'total': 'monetary_value'}, inplace=True)
quantiles = rfm.quantile(q=[0.25,0.5,0.75])
quantiles = quantiles.to_dict()
def RScore(x,p,d):
if x <= d[p][0.25]:
return 1
elif x <= d[p][0.50]:
return 2
elif x <= d[p][0.75]:
return 3
else:
return 4
def FMScore(x,p,d):
if x <= d[p][0.25]:
return 4
elif x <= d[p][0.50]:
return 3
elif x <= d[p][0.75]:
return 2
else:
return 1
rfm['R_Quartile'] = rfm['recency'].apply(RClass, args=('recency',quantiles,))
rfm['F_Quartile'] = rfm['frequency'].apply(FMClass, args=('frequency',quantiles,))
rfm['M_Quartile'] = rfm['monetary_value'].apply(FMClass, args=('monetary_value',quantiles,))
rfm['RFMClass'] = rfm.R_Quartile.map(str) \
+ rfm.F_Quartile.map(str) \
+ rfm.M_Quartile.map(str)我现在得到的是这样的数据框架:
customer_id | RFM
2 | 313
5 | 131
3 | 414我想要一个按月细分的RFM分数,如下所示:
customer_id | Jan | Feb | ....| Dec
2 | 313 | 324 | ....| 121
5 | 131 | 342 | ....| 212
3 | 414 | 113 | ....| 333现在我的问题是,我不知道如何让上面的计算都基于月份,我想在一年中循环12次,但循环太大了,有什么有效的方法吗?
发布于 2018-07-31 09:16:14
我并没有在您的示例中一直使用这个方法,但我相信这将会起到作用。
首先,确保您的日期实际上是datetime格式,如果您还没有这样做。
data['date'] = pd.to_datetime(data['date'])然后,创建一个包含月份的新列。
data['month_id'] = data['date'].dt.strftime('%B')然后,您可以对矩阵进行分组和拆分,以获得一个矩阵,其中列为month_id,行为customer_id。下面是一个仅包含一个聚合的示例。
data.groupby(['customer_id', 'month_id'])['total'].sum().unstack()给予:
month_id January March
customer_id
2 39.0 10.0
3 NaN 10.0
5 21.0 NaN从那里,您应该能够将您的RFM分数应用到每一列。请注意,由于您有多个聚合,因此您的数据帧上实际上会有一个multiIndex。但原理是一样的。
https://stackoverflow.com/questions/51603485
复制相似问题