如何用Pandas生成按用户分组的历史爽约占比列?
问题
现有不含最后两列的Pandas DataFrame,已生成previous-missed-appointments列(记录每行对应的历史爽约次数),需生成最后一列proportion-previous-missed。计算规则为:按name分组,每行的历史爽约次数除以该行之前的总预约次数(爽约+到场次数),例如示例中第9行的0.4由「2次爽约 ÷ 5次总预约」得出。
解决方案
步骤说明
- 先按
name和预约时间排序,确保历史记录的时间顺序正确(否则计算的历史数据会出错); - 对每个
name分组,计算当前行之前的总预约次数——用cumcount()方法,它会给分组内每行分配从0开始的序号,这个序号就是当前行之前的总预约次数; - 计算比例,同时处理除数为0的情况(比如用户第一次预约时,之前没有任何记录,此时可将比例设为0或
NaN)。
代码实现
假设DataFrame名为df,预约时间列名为appointment-date,代码如下:
import pandas as pd import numpy as np # 按姓名和预约时间排序,保证历史顺序正确 df = df.sort_values(['name', 'appointment-date']) # 计算每个用户当前行之前的总预约次数 df['total-previous-appointments'] = df.groupby('name').cumcount() # 计算历史爽约比例,处理除数为0的情况 df['proportion-previous-missed'] = np.where( df['total-previous-appointments'] > 0, df['previous-missed-appointments'] / df['total-previous-appointments'], 0 # 若需显示空值,可替换为np.nan )
代码解释
sort_values():确保每个用户的预约记录按时间先后排列,这是计算历史数据的前提;groupby('name').cumcount():给每个用户的预约记录从0开始编号,编号值等于当前行之前的总预约次数(比如第1次预约编号0,之前无预约;第6次预约编号5,之前有5次预约);np.where():避免除数为0的报错,当总预约次数为0时(第一次预约),直接返回设定值(0或NaN),否则执行除法计算比例。
内容的提问来源于stack exchange,提问作者pooya ensafi
相关产品推荐
相关产品推荐

