随机地将参与者重新分配到组中,这样原来来自同一组的参与者不会最终加入到同一组中

2024-10-02 06:24:48 发布

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

我基本上是在做这种蒙特卡罗分析,我随机地把实验中的参与者重新分配到新的组中,然后重新分析随机的新组中的数据。所以我想做的是:

参与者最初分为八组,每组四名。我想随机地将每个参与者重新分配到一个新的组中,但我不希望任何参与者与另一个来自同一原始组的参与者组成一个新的组。在

以下是我所做的:

import random
import pandas as pd
import itertools as it

data = list(it.product(range(8),range(4)))
test_df = pd.DataFrame(data=data,columns=['group','partid'])
test_df['new_group'] = None

for idx, row in test_df.iterrows():
    start_group = row['group']
    takens      = test_df.query('group == @start_group')['new_group'].values
    fulls       = test_df.groupby('new_group').count().query('partid >= 4').index.values
    possibles   = [x for x in test_df['group'].unique() if (x not in takens)
                                                      and (x not in fulls)]
    test_df.loc[idx,'new_group'] = random.choice(possibles)

这里的基本思想是,我随机地将一个参与者重新分配到一个新的组中,并且约束条件是(a)新组中没有他们原来的组伙伴之一,并且(b)新组没有4个或更多的参与者已经重新分配给它。在

这种方法的问题是,很多时候,当我们尝试重新分配最后一个组时,剩下的唯一组槽位于同一组中。我也可以在失败时尝试重新随机,直到成功,但这感觉很傻。另外,我想做100个随机的重新分配,这样的方法可能会变得非常慢。。。。在

所以必须有一个更聪明的方法来做到这一点。我也觉得应该有一个更简单的方法来解决这个问题,考虑到这个目标有多简单(但我意识到这可能会误导你…)


Tags: 方法intestimportdfnewdataas
1条回答
网友
1楼 · 发布于 2024-10-02 06:24:48

编辑:更好的解决方案


在沉睡之后,我发现了一个更好的解决方案。在

样本数据

import random
import numpy as np
import pandas as pd
import itertools as it

np.random.seed(0)
numGroups=4
numMembers=4

data = list(it.product(range(numGroups),range(numMembers)))
df = pd.DataFrame(data=data,columns=['group','partid'])

解决方案

^{pr2}$

注意对角线。在

^{3}$

从上到下沿对角线。在

newGroups = []
for i in range(numGroups):
    newGroups.append(np.diagonal(g[i:i+numMembers]))

In [106]: newGroups
Out[106]: 
[array([2, 3, 1, 0]),
 array([3, 1, 0, 2]),
 array([1, 0, 2, 3]),
 array([0, 2, 3, 1])]

newGroups = np.ravel(newGroups)
df["newGroups"] = newGroups

In [110]: df
Out[110]: 
    group  partid  newGroups
0       0       0          2
1       0       1          3
2       0       2          1
3       0       3          0
4       1       0          3
5       1       1          1
6       1       2          0
7       1       3          2
8       2       0          1
9       2       1          0
10      2       2          2
11      2       3          3
12      3       0          0
13      3       1          2
14      3       2          3
15      3       3          1

老办法:蛮力法


结果比我想象的要难得多。。。在

我有一个蛮力的方法,基本上是猜测不同的组排列,直到最后得到一个组中每个人都是不同的组。与您所展示的相比,这种方法的好处是,它不会因为“在最后耗尽组”而受到影响。在

它可能会变慢,但对于8个小组,每个小组4个成员,它是快的。在

样本数据

import random
import numpy as np
import pandas as pd
import itertools as it

random.seed(0)
numGroups=4
numMembers=4

data = list(it.product(range(numGroups),range(numMembers)))
df = pd.DataFrame(data=data,columns=['group','partid'])

解决方案

g = np.repeat(range(numGroups),numMembers).reshape((numGroups,numMembers))

In [4]: g
Out[4]: 
array([[0, 0, 0, 0],
       [1, 1, 1, 1],
       [2, 2, 2, 2],
       [3, 3, 3, 3]])

def reArrange(g):
    g = np.transpose(g)
    g = [np.random.permutation(x) for x in g]
    return np.transpose(g)

# check to see if any members in each old group have duplicate new groups
# if so repeat
while np.any(np.apply_along_axis(lambda x: len(np.unique(x))<numMembers,1,g)):
    g = reArrange(g)

df["newGroup"] = g.ravel()

In [7]: df
Out[7]: 
    group  partid  newGroup
0       0       0         2
1       0       1         3
2       0       2         1
3       0       3         0
4       1       0         0
5       1       1         1
6       1       2         2
7       1       3         3
8       2       0         1
9       2       1         0
10      2       2         3
11      2       3         2
12      3       0         3
13      3       1         2
14      3       2         0
15      3       3         1

相关问题 更多 >

    热门问题