Python 3.x 大熊猫的月RFM分析

Python 3.x 大熊猫的月RFM分析,python-3.x,pandas,dataframe,group-by,Python 3.x,Pandas,Dataframe,Group By,我最近在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

我最近在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
 customer_id | RFM
  2          | 313 
  5          | 131   
  3          | 414
 customer_id | Jan | Feb | ....| Dec 
  2          | 313 | 324 | ....| 121
  5          | 131 | 342 | ....| 212   
  3          | 414 | 113 | ....| 333
为了计算全年的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)
我想要一个月的细分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
 customer_id | RFM
  2          | 313 
  5          | 131   
  3          | 414
 customer_id | Jan | Feb | ....| Dec 
  2          | 313 | 324 | ....| 121
  5          | 131 | 342 | ....| 212   
  3          | 414 | 113 | ....| 333

现在我的问题是,我不知道如何根据月份进行上述所有计算,我曾想过在一年中循环12次,但循环太大,有没有有效的方法

我还没有完全理解你的例子,但我相信这会奏效

首先,如果您还没有使用
datetime
格式,请确保您的日期实际为该格式

data['date'] = pd.to_datetime(data['date'])
然后,创建一个新列来保存月份

data['month_id'] = data['date'].dt.strftime('%B')
然后,您可以分组并取消堆叠,以获得列上带有
month\u id
和行上带有
customer\u 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分数应用到每一列。注意,您的数据帧上实际上有一个多索引,因为您有多个聚合。但原则是一样的