按照权值生成列表内的内容
生成随机的11位电话号码
def make_phone(num):
lt=[]
ahead=np.random.randint(125,195,num)
follow=np.random.randint(0,99999999,num)
for a,f in zip(ahead,follow):
k=f'{a}{f:0>8}'
lt.append(k)
return lt
make_phone(100)
# ----- 结果 -----
['18262627913',
'15524909880',
'16417080083',
……
'19480918346',
'14774805532',
'12893994298',
'14275982379',]
生成n个时间,需要符合正常作息的时段
def make_n_time(num):
# 0~23时间的权值
time_rights=[3.2,2.4,1.8,0.7,0.4,0.35,0.56,0.9,1.2,1.8,2,2.5,1.8,2.5,2.6,2.8,2.5,3.1,2.4,3.8,4.5,4.2,3.6,3.3]
# 转换为百分比
time_rights=[rights/sum(time_rights) for rights in time_rights]
times=[]
for i in range(num):
time_get=np.random.choice(range(24),p=time_rights)
times.append(f'{time_get:0>2}:{(np.random.randint(0,60)):0>2}:{np.random.randint(0,60):0>2}')
return times
按照作息时间制作的每小时交易次数
随机返回num个在指定时间范围内的日期,要求周末占比多,指定日期的前三天也要多
def make_n_date(mnt,num,ver_date_start,ver_date_end):
date_begin=f"2024-{mnt:0>2}-01"
# 日期范围列表
date_list=pd.date_range(date_begin,pd.Timestamp(date_begin)+pd.offsets.MonthEnd(0))
# 这个月有多少天
daysofmonth=(pd.Timestamp(date_begin)+pd.offsets.MonthEnd(0)-pd.to_datetime(date_begin)).days+1
# 每月初始权值
rights=np.ones(daysofmonth)
ll=pd.Series(date_list).dt.dayofweek
week_val=ll.values # 星期几
week_index=ll.index.values # 对应位置
# 找出周五~周日的日志
# 按照权值随机赋予权值大小
for indx,val in zip(week_index,week_val):
if val in(6,5,4):
rights[indx]=(np.random.choice([1,2,3,4,5],1,p=[0.1,0.3,0.3,0.2,0.1]))
# 找到符合日期区间的标签
target_index=np.argwhere((date_list>=ver_date_start) & (date_list<=ver_date_end))
# 找到目标区间的前三天的标签
target_index=target_index.flatten()[:3]
# 求周末时期的权重
avg_right=np.mean(rights)
# 目标区间的权重分贝为周末权重的10倍、8倍、以及3倍,依次衰减
rights[target_index]=[avg_right*10,avg_right*8,avg_right*3]
# 将权值化为为百分比
rights=rights/sum(rights)
# 抽取num个结果,并将返回值从datetime64类型改为str
date_real=np.random.choice(date_list.astype(str),num,p=rights)
return date_real
每周交易额
随机返回num个在指定时间范围内的日期,要求周末占比多,指定日期的前三天也要多
生成抽卡消费列表,有n个充钱档次,没人会随机抽m次,可设置人数以及抽卡率,抽卡次数需要符合正态分布
# usr_cnt 用户总数
# free_usr_rate 用户非付费率
# mean_times 用户平均消费次数
# std_dev 用户平均消费次数的标准差
def make_all_usr_amount(usr_cnt,free_usr_rate,mean_times,std_dev):
# 将付费用户插入总表
all_usr_amount=list(np.zeros(usr_cnt)) # 所有用户,付费初始为0
# 消费详细金额
all_detail_comsume=list(np.zeros(usr_cnt))
# 消费日期
all_datetime_comsume=[' ' for _ in range(usr_cnt)]
pay_usr_num=usr_cnt-int(usr_cnt*free_usr_rate)
# 按照标准正态分布的模板 mean=0 std=1
scaled_normal = np.random.normal(0, 1, pay_usr_num)
# 缩放和平移这个分布到标准分布的期望的范围
mean=mean_times
std_dev=std_dev
gacha = mean*10 + std_dev * scaled_normal # 避免出现负数先放大10倍
gacha=gacha/10 # 还原原来大小
gacha = [max(x,1) for x in gacha] # 付费用户至少1次消费
gacha = np.round(gacha).astype(int)
std_amount=[30,68,98,128,326,648] # 充钱档次
usr_amount_lt=[]
detail_comsume=[]
# 求付费用户每次抽取对应的时间与金额gacha为所有用户的抽取次数
# 抽卡次数等于3为阈值,分别设置消费次数的权值
for i in gacha:
if i<3:
consum_right=[50,10,5,5,5,5]
else:
consum_right=[5,5,10,20,30,40]
consum_right=[r/sum(consum_right) for r in consum_right]
amount_lt=np.random.choice(std_amount,i,p=consum_right)
# 消费列表
detail_comsume.append(amount_lt)
# 消费总金额
total_amount=sum(amount_lt)
usr_amount_lt.append(total_amount)
# 付费用户随机插入其中的位置,replace=False不放回,根据随机标签决定位置分布
# 用pop从原数据列表中抽取数据
insert_index=list(np.random.choice(range(usr_cnt),pay_usr_num,replace=False))
for idx in insert_index:
all_usr_amount[idx]=usr_amount_lt.pop()
all_detail_comsume[idx]=detail_comsume.pop()
# 返回为DataFrame
df=pd.DataFrame({'usr_amount':all_usr_amount,'detail_comsume':all_detail_comsume})
df.reset_index(inplace=True)
df.rename(columns={'index':'uid'},inplace=True) # 生成uid
df['uid']=df['uid']+10000000 # uid偏移
df.uid=df.uid.map(str) # 修改格式类型
return df
以一个月为跨度,按照以上权值设置的流水模拟
年龄设置
生成不同年龄段,并让每个年龄段的数量受权值控制,需要在合适的年龄衰减或攀升
不同年龄段消费能力不同,根据消费能力给表插入年龄
def make_ages(mean_amount,amount_list):
right1=np.ones(len(np.arange(8,12)))*2
right2=np.ones(len(np.arange(12,16)))*3
right3=np.linspace(3,15,len(range(16,22)))
right4=np.linspace(15,4,len(range(22,35)))
right5=np.linspace(4,0.5,len(range(35,45)))
right6=np.linspace(0.1,0,len(range(45,101)))
# 获取总的各年龄段的权值
rights=np.concatenate([right1,right2,right3,right4,right5,right6])
rights=rights/sum(rights)
# 初始年龄列表
age_list=np.random.choice(range(8,101),len(amount_list),p=rights)
# 消费力低的idx
index0=amount_list[(amount_list<mean_amount*0.2)].index
# 高于平均值的idx
index1=amount_list[(amount_list>mean_amount) & (amount_list<mean_amount*2)].index
# 平均值2倍以上的idx
index2=amount_list[amount_list>mean_amount*2].index
# 根据付费年征修改年龄
# 未成付费能力弱,拉高抽取到低龄的可能性
rights=np.concatenate([right1*5,right2*3,right3,right4,right5,right6])
rights=rights/sum(rights)
for idx in index0:
age_list[idx] = np.random.choice(range(8,101),p=rights)
# 中学付费欲望较强,拉高抽取到中学的可能性
rights=np.concatenate([right1,right2,right3*1.8,right4*1.5,right5,right6])
rights=rights/sum(rights)
for idx in index1:
age_list[idx] = np.random.choice(range(8,101),p=rights)
# 中学到青年付费欲望最强,拉高抽取到青年的可能性
rights=np.concatenate([right1,right2,right3*1.2,right4*2,right5,right6])
rights=rights/sum(rights)
for idx in index2:
age_list[idx] = np.random.choice(range(8,101),p=rights)
return age_list
根据这个消费能力和年龄权值的配置,经过sql语句分类后获得如下表格
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。