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

2024-05-16 01:44:49 发布

您现在位置:Python中文网/ 问答频道 /正文

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

我有以下excel文件:

enter image description here

我想做的是重新分配商家(Mer\u id),以便每个用户(Origin\u pool)获得与以前相同数量的商家,但不同的商家集。例如,在重新分配之后,Nick将收到3个Mer_id,但不是:30303、101020、220340。Anna将收到4个merchants,但不是2340130310231、2030230、2310505,依此类推。当然,一个商户不能分配给多个人

到目前为止,我所做的是找到每个用户必须接收的商户总数,并随机给他们一个以前没有分配给他们的mer\u id。在我找到一个不同的mer\u 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])

但考虑到将来我可能会有超过18行的数据,这一点也不高效

有没有什么图书馆能做到这一点,或者有什么方法能提高效率?谢谢


Tags: 用户nameiddforigindictdestpool
2条回答

我的解决方案使用字典和列表,我打印结果,但是您可以用它创建一个新的数据帧

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个列表,在代码开头初始化: 成对->;它返回你的池列表(最后一个) 改组->;它返回随机生成的pairs池,并且已经出现在excel的pool pairs中 静止->;处理函数pullpush中的重复池对

pullpsuh函数首先出现,因为它将在不同的情况下被调用

程序的第一部分是一个随机算法,用于从mer\u id(商人)和origin\u pool(池)进行配对。 如果该对不在excel中,则会转到“对”列表,否则会转到“重新排列”列表

根据重组特征,调用另一个随机算法,或由pullpush函数处理

如果您只执行一次代码,并打印(对),您可能会发现一个包含15个、14个池对的列表,而池对的数目小于18个。 然后,如果你打印(重新洗牌),你会看到其余的配对,使18。 要在pairs变量中获得完整的18个匹配,必须运行: pullpush(重新洗牌)

这里的输出是通过运行以下代码获得的: pullpush(改组)

如果你想控制mer\u id和origin\u pool不能重复3轮,你可以加载其他2个excel并拆分 把它们分为老派2和老派3

[[8348201,'Anna'],[53256236,'Anna'],[9295,'Anna'],[54240,'Anna'],[30303,'Marios'],[101020,'Marios'],[959295,'Marios'],[2030230,'George'],[310231,'George'],[23401330,'George'],[2341134,'Nick'],[178345,'Marios'],[220340,'Marios'],[737635,'George'],[2030230,'George'],[928958,'Nick'],[5560503,'George'],[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) 

相关问题 更多 >