重新分发商户id列表,以便每个用户接收不同的商户集,但数量相同-Python
更新:这无法100%解决,因为每个用户必须接收的商户数量不同。因此,一些用户可能会得到与以前相同的商家。但是,如果没有其他不同的商户,是否可以让他们获得相同的商户 我有以下excel文件: 我想做的是重新分配商家(Mer_id),这样每个用户(Origin_pool)就可以获得与以前相同数量的商家,但不同的商家集。例如,在重新分配之后,Nick将收到3个Mer_id,但不是:30303101020220340。Anna将收到4个商户,但不包括23401230310231055等。当然,一个商户不能分配给多个人 到目前为止,我所做的是找到每个用户必须接收的商户总数,并随机给他们一个以前没有分配给他们的mer_id。在我找到不同的商户id后,我将其从列表中删除,这样其他用户就不会收到相同的商户:重新分发商户id列表,以便每个用户接收不同的商户集,但数量相同-Python,python,pandas,Python,Pandas,更新:这无法100%解决,因为每个用户必须接收的商户数量不同。因此,一些用户可能会得到与以前相同的商家。但是,如果没有其他不同的商户,是否可以让他们获得相同的商户 我有以下excel文件: 我想做的是重新分配商家(Mer_id),这样每个用户(Origin_pool)就可以获得与以前相同数量的商家,但不同的商家集。例如,在重新分配之后,Nick将收到3个Mer_id,但不是:30303101020220340。Anna将收到4个商户,但不包括23401230310231055等。当然,一个商户
import pandas as pd
import numpy as np
df=pd.read_excel('dup_check_origin.xlsx')
dfcounts=df.groupby(['Origin_pool']).size().reset_index(name='counts')
Origin_pool=list(dfcounts['Origin_pool'])
counts=list(dfcounts['counts'])
dict_counts = dict(zip(Origin_pool, counts))
dest_name=[]
dest_mer=[]
for pool in Origin_pool:
pername=0
#for j in range(df.shape[0]):
while pername<=dict_counts[pool]:
rn=random.randint(0,df.shape[0]-1)
rid=df['Mer_id'].iloc[rn]
if (pool!=df['Origin_pool'].iloc[rn]):
#new_dict[pool]=rid
pername+=1
dest_name.append(pool)
dest_mer.append(rid)
df=df.drop(df.loc[df['Mer_id']==rid].index[0])
将熊猫作为pd导入
将numpy作为np导入
df=pd.read\u excel('dup\u check\u origin.xlsx')
dfcounts=df.groupby(['Origin\u pool']).size().reset\u index(name='counts')
来源池=列表(dfcounts['Origin\U pool'])
计数=列表(dfcounts['counts'])
dict_counts=dict(zip(原始池,计数))
目的地名称=[]
目的地=[]
对于Origin_池中的池:
pername=0
#对于范围内的j(df.形状[0]):
虽然pername我的解决方案使用字典和列表,但我打印结果,但您可以使用它创建一个新的数据帧
from random import shuffle
import pandas as pd
df = pd.read_excel('dup_check_origin.xlsx')
dpool = {}
mers = list(df.Mer_id.unique())
shuffle(mers)
for pool in df.Origin_pool.unique():
dpool[pool] = list(df.Mer_id[df.Origin_pool == pool])
for key in dpool.keys():
inmers = dpool[key]
cnt = len(inmers)
new = [x for x in mers if x not in inmers][:cnt]
mers = [x for x in mers if x not in new]
print(key, new)
你问了几天后,但我认为这是一个防弹密码。
您可以使用整个代码创建函数或类。
我只创建了一个,这是一个递归的,用来处理剩余部分
有3个列表,在代码开头初始化:
结对->返回您的池列表(最后一个)
重新洗牌->返回随机生成的配对池,该配对池已经出现在excel中的配对池中
仍然->以处理函数pullpush中的重复池对
pullpsuh函数首先出现,因为它将在不同的情况下被调用
程序的第一部分是一个随机算法,用于从mer_id(商家)和origin_pool(池商)进行配对。
如果配对不在excel中,则会转到配对列表,否则会转到重新排列列表
根据重组特征,调用另一个随机算法,或者由pullpush函数处理
如果按原样执行一次代码并打印(对),您可能会发现一个列表,其中包含15个、14个池对,任何小于18个的池对。
然后,如果您打印(重新排列),您将看到其余的对,使18。
要在pairs变量中获得完整的18个匹配,必须运行:
pullpush(重新洗牌)
此处的输出是通过运行以下代码获得的:
pullpush(改组)
如果您想控制mer_id和origin_pool在3轮中不重复,您可以加载其他2个excel并拆分
将它们分为oldpair2和oldpair3
[8348201,“安娜”]、[53256236,“安娜”]、[9295,“安娜”]、[54240,“安娜”]、[30303,“马里奥斯”]、[101020,“马里奥斯”]、[959295,“马里奥斯”]、[2030230,“乔治”]、[310231,“乔治”]、[23401230,“乔治”]、[2341134,“尼克”、[178345,“马里奥斯”]、[220340,“马里奥斯”、[737635”,“乔治”、[2030230”,“乔治”、[928958”,“尼克”、[60503]、[60503],[34646,‘尼克’]]
守则:
import pandas as pd
import random
df=pd.read_excel('dup_check_origin.xlsx')
oldpair = df.values.tolist() #check previous pooling pairs
merchants = df['Mer_id'].values.tolist() #convert mer_id in list
poolers = df['Origin_pool'].values.tolist() #convert mer_id in list
random.shuffle(merchants) #1st step shuffle
pairs = [] #empty pairs list
reshuffle = [] #try again
still = [] #same as reshuffle for pullpush
def pullpush(repetition):
replacement = repetition #reshuffle transfer
for re in range(len(replacement)):
replace = next(r for r in pairs if r not in replacement)
repair = [[replace[0],replacement[re][1]],
[replacement[re][0],replace[1]]]
if repair not in oldpair:
iReplace = pairs.index(replace)#get index of pair
pairs.append(repair)
del pairs[iReplace] # remove from pairs
else:
still.append(repair)
if still:
pullpush(still) #recursive call
for p in range(len(poolers)):#avoid more merchants than poolers
pair = [merchants[p],poolers[p]]
if pair not in oldpair:
pairs.append(pair)
else:
reshuffle.append(pair)
if reshuffle:
merchants_bis = [x[0] for x in reshuffle]
poolers_bis = [x[1] for x in reshuffle]
if len(reshuffle) > 2: #shuffle needs 3 or more elements
random.shuffle(merchants_bis)
reshuffle = [] #clean before the loop
for n in range(len(poolers_bis)):
new_pair = [merchants_bis[n],poolers_bis[n]]
if new_pair not in oldpair:
pairs.append(new_pair)
else:
reshuffle.append(new_pair)
if len(reshuffle) == len(poolers_bis):#infinite loop
pullpush(reshuffle)
# double pairs and different poolers
elif (len(reshuffle) == 2 and not[i for i in reshuffle[0] if i in reshuffle[1]]):
merchants_bis = [merchants_bis[1],merchants_bis[0]]
new_pair = [[merchants_bis[1],poolers_bis[0]],
[merchants_bis[0],poolers_bis[1]]]
if new_pair not in oldpair:
pairs.append(new_pair)
else:
reshuffle.append(new_pair)
pullpush(reshuffle)
else: #one left or same poolers
pullpush(reshuffle)
我不确定你是否总能做到这一点:如果Anne有一个商户id
,而Bob有两个,你就会有问题。一旦你检查了这个特定的案例,你就可以将你所有的商户id移动与单个用户相关联的id的最大数量(假设一个用户的所有条目都放在一起,如你的示例所示).Edit:在您的情况下,George有6个ID,因此将商户ID循环6次。