重新分发商户id列表,以便每个用户接收不同的商户集,但数量相同-Python

重新分发商户id列表,以便每个用户接收不同的商户集,但数量相同-Python,python,pandas,Python,Pandas,更新:这无法100%解决,因为每个用户必须接收的商户数量不同。因此,一些用户可能会得到与以前相同的商家。但是,如果没有其他不同的商户,是否可以让他们获得相同的商户 我有以下excel文件: 我想做的是重新分配商家(Mer_id),这样每个用户(Origin_pool)就可以获得与以前相同数量的商家,但不同的商家集。例如,在重新分配之后,Nick将收到3个Mer_id,但不是:30303101020220340。Anna将收到4个商户,但不包括23401230310231055等。当然,一个商户

更新:这无法100%解决,因为每个用户必须接收的商户数量不同。因此,一些用户可能会得到与以前相同的商家。但是,如果没有其他不同的商户,是否可以让他们获得相同的商户

我有以下excel文件:

我想做的是重新分配商家(Mer_id),这样每个用户(Origin_pool)就可以获得与以前相同数量的商家,但不同的商家集。例如,在重新分配之后,Nick将收到3个Mer_id,但不是:30303101020220340。Anna将收到4个商户,但不包括23401230310231055等。当然,一个商户不能分配给多个人

到目前为止,我所做的是找到每个用户必须接收的商户总数,并随机给他们一个以前没有分配给他们的mer_id。在我找到不同的商户id后,我将其从列表中删除,这样其他用户就不会收到相同的商户:

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次。