用户行为分析的时候,经常需要将特定时间段的用户分类,一般来说分为活跃用户(最近一次服务成单(支付)时间距今小于30天)、沉默用户(最近一次服务成单(支付)时间距今大于30天小于等于60天)、流失用户(最近一次服务成单(支付)时间距今大于60天)
pay_time:下单时间
最近一次服务成单(支付)时间距今小于30天
import pandas as pd
today = pd.to_datetime('today').normalize()
active_user = df[df['pay_time'].between(today - pd.offsets.Day(30), today)]
最近一次服务成单(支付)时间距今大于30天小于等于60天
generally_user = df[df['pay_time'].between(today - pd.offsets.Day(60), today - pd.offsets.Day(31))]
最近一次服务成单(支付)时间距今大于60天
lost_user = df[df['pay_time'] < (today - pd.offsets.Day(60))]
全量
参考代码
# 设置联合索引
@property
def uk(self) -> tuple:
return ('patient_id',)
def insert(self, df: DataFrame, if_exists='replace'):
# 保存到数据库
assert self.uk, ValueError("joint_index cannot be empty")
df = self.fillNone(df)
self.log(f'Saving to {self.TABLE}, data length: {len(df)}')
get_type = self.mapping_df_types(df)
df.to_sql(self.TABLE, con=self.engine, if_exists=if_exists, index=False, index_label=False, dtype=get_type)
i_name, i_key = '_'.join(self.uk), ','.join(self.uk)
sql_index = f'ALTER TABLE {self.TABLE} add unique key {i_name}({i_key});'
sql_create_at = f'ALTER TABLE {self.TABLE} ADD COLUMN `create_at` datetime NOT NULL DEFAULT current_timestamp()'
sql_update_at = f'ALTER TABLE {self.TABLE} ADD COLUMN `update_at` datetime NOT NULL DEFAULT current_timestamp()' \
f' ON UPDATE current_timestamp();'
self.execute_sql(sql_index)
self.execute_sql(sql_create_at)
self.execute_sql(sql_update_at)
增量
做用户增量的时候,每次将180天内有下过单的用户输出出来,做增量
参考代码
DUPLICATE KEY UPDATE 这个是关键,针对MySQL来说,只要设置了唯一值,那么就会根据唯一值进行更新或者添加。
def many_update_or_insert(self, df: DataFrame):
df = self.fillNone(df)
# 构造每个列对应的数据,对应于上面的((value1, value2, value3))
data_list = [tuple(i) for i in df.values]
if len(data_list) == 0:
self.log('当前时间没有数据....')
else:
# 可以删除不要的列或者数据库没有的列名
# 重新构造df,用上面的columns,到这里你要保证你所有列都要准备往数据库写入了
app_key = [' {name}=values({name})'.format(name=column) for column in list(df.columns)]
all_duplicate_key = ','.join(app_key)
# 构造符合sql语句的列,因为sql语句是带有逗号分隔的,(这个对应上面的sql语句的(column1, column2, column3))
str_columns = ','.join(list(df.columns))
data_list = [tuple(i) for i in df.values] # 每个元组都是一条数据,根据df行数生成多少元组数据
# 计算一行有多少value值需要用字符串占位
s_count = len(data_list[0]) * "%s,"
# 构造sql语句
insert_sql = "insert into " + "{}".format(self.TABLE) + " (" + str_columns + ") values (" + \
s_count[:-1] + ")" + "on DUPLICATE KEY UPDATE " + all_duplicate_key
self.execute_sql(insert_sql, data_list)