使用 python 进行区块随机化?
Block randomization using python?
我有以下输入 table (df):
ColumnA
ColumnB
Blocks
A
12
1
B
32
1
C
44
1
D
76
2
E
99
2
F
123
2
G
65
2
H
87
3
I
76
3
J
231
3
k
80
4
l
55
4
m
27
5
n
67
5
o
34
5
我想执行块随机化,这样它从每个块中选择一个值(从 1,2,3,4,5 中选择一个值)并将其创建为单独的 table。
输出应如下所示:
ColumnA
ColumnB
Blocks
Groups
B
32
1
A1
E
99
2
A1
I
76
3
A1
l
55
4
A1
m
27
5
A1
A
12
1
A2
F
123
2
A2
k
80
3
A2
m
27
4
A2
n
67
5
A2
C
44
1
A3
H
87
2
A3
J
231
3
A3
n
67
4
A3
o
34
5
A4
D
76
1
A4
G
65
2
A4
随机选择行,这样每组都有所有块(均匀分布)。
到目前为止我尝试了什么?
df = df.groupby('blocks').apply(lambda x: x.sample(frac=1,random_state=1234)).reset_index(drop=True)
treatment_groups = [f"A{i}" for i in range(1, n+1)]
df['Groups'] = (df.index // n).map(dict(zip(idx, treatment_groups)))
这不会根据块列随机化。我该怎么做?
让我们尝试定义一个函数,从每个 block
:
中生成 random
个样本
def random_samples(n):
for i in range(1, n+1):
for _, g in df.groupby('Blocks'):
yield g.sample(n=1).assign(Groups=f'A{i}')
sampled = pd.concat(random_samples(4), ignore_index=True)
>>> sampled
ColumnA ColumnB Blocks Groups
0 A 12 1 A1
1 D 76 2 A1
2 I 76 3 A1
3 k 80 4 A1
4 n 67 5 A1
5 C 44 1 A2
6 G 65 2 A2
7 J 231 3 A2
8 l 55 4 A2
9 m 27 5 A2
10 B 32 1 A3
11 G 65 2 A3
12 H 87 3 A3
13 l 55 4 A3
14 m 27 5 A3
15 B 32 1 A4
16 F 123 2 A4
17 I 76 3 A4
18 l 55 4 A4
19 m 27 5 A4
在您的代码中 .sample(frac = 1)
returns 100% 的样本,即所有样本。你想要 .sample(n=1)
的版本,例如,如果你只想要一组,你会做
df.groupby('Blocks').apply(lambda x: x.sample(n=1, random_state=1234))
得到
ColumnA ColumnB Blocks
Blocks
1 0 A 12 1
2 3 D 76 2
3 7 H 87 3
4 10 k 80 4
5 12 m 27 5
例如,要获得 5 个组,您将使用 n=5
和 replace=True
(因为有些组的元素少于 5 个),然后重新排列:
df = df.groupby('Blocks').apply(lambda x: x.sample(n=5, replace = True, random_state=1234)).reset_index(drop = True)
df['Groups'] = 'A' + df.groupby('Blocks').cumcount().astype(str)
df.sort_values('Groups')
生产
ColumnA ColumnB Blocks Groups
-- --------- --------- -------- --------
0 C 44 1 A0
20 o 34 5 A0
5 G 65 2 A0
15 l 55 4 A0
10 J 231 3 A0
1 B 32 1 A1
21 n 67 5 A1
6 G 65 2 A1
16 l 55 4 A1
11 I 76 3 A1
22 m 27 5 A2
17 k 80 4 A2
12 H 87 3 A2
7 F 123 2 A2
2 A 12 1 A2
13 H 87 3 A3
8 E 99 2 A3
18 l 55 4 A3
3 A 12 1 A3
23 m 27 5 A3
14 H 87 3 A4
9 D 76 2 A4
19 k 80 4 A4
4 A 12 1 A4
24 m 27 5 A4
- 它确实不是随机的,但会根据需要分组
- 源数据帧的顺序将影响块分配给 Group
的顺序
df = pd.DataFrame({'ColumnA': ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'k', 'l', 'm', 'n', 'o'],
'ColumnB': [12, 32, 44, 76, 99, 123, 65, 87, 76, 231, 80, 55, 27, 67, 34],
'Blocks': [1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5]})
# generate a series that is "A{n}" where "n" is occurrence# of "Block"
sg = df.groupby("Blocks").apply(lambda g: pd.Series([f"A{i+1}"
for i in range(len(g))],name="Group")).explode().reset_index(drop=True)
df.join(sg)
ColumnA
ColumnB
Blocks
Group
0
A
12
1
A1
1
B
32
1
A2
2
C
44
1
A3
3
D
76
2
A1
4
E
99
2
A2
5
F
123
2
A3
6
G
65
2
A4
7
H
87
3
A1
8
I
76
3
A2
9
J
231
3
A3
10
k
80
4
A1
11
l
55
4
A2
12
m
27
5
A1
13
n
67
5
A2
14
o
34
5
A3
我有以下输入 table (df):
ColumnA | ColumnB | Blocks |
---|---|---|
A | 12 | 1 |
B | 32 | 1 |
C | 44 | 1 |
D | 76 | 2 |
E | 99 | 2 |
F | 123 | 2 |
G | 65 | 2 |
H | 87 | 3 |
I | 76 | 3 |
J | 231 | 3 |
k | 80 | 4 |
l | 55 | 4 |
m | 27 | 5 |
n | 67 | 5 |
o | 34 | 5 |
我想执行块随机化,这样它从每个块中选择一个值(从 1,2,3,4,5 中选择一个值)并将其创建为单独的 table。
输出应如下所示:
ColumnA | ColumnB | Blocks | Groups |
---|---|---|---|
B | 32 | 1 | A1 |
E | 99 | 2 | A1 |
I | 76 | 3 | A1 |
l | 55 | 4 | A1 |
m | 27 | 5 | A1 |
A | 12 | 1 | A2 |
F | 123 | 2 | A2 |
k | 80 | 3 | A2 |
m | 27 | 4 | A2 |
n | 67 | 5 | A2 |
C | 44 | 1 | A3 |
H | 87 | 2 | A3 |
J | 231 | 3 | A3 |
n | 67 | 4 | A3 |
o | 34 | 5 | A4 |
D | 76 | 1 | A4 |
G | 65 | 2 | A4 |
随机选择行,这样每组都有所有块(均匀分布)。
到目前为止我尝试了什么?
df = df.groupby('blocks').apply(lambda x: x.sample(frac=1,random_state=1234)).reset_index(drop=True)
treatment_groups = [f"A{i}" for i in range(1, n+1)]
df['Groups'] = (df.index // n).map(dict(zip(idx, treatment_groups)))
这不会根据块列随机化。我该怎么做?
让我们尝试定义一个函数,从每个 block
:
random
个样本
def random_samples(n):
for i in range(1, n+1):
for _, g in df.groupby('Blocks'):
yield g.sample(n=1).assign(Groups=f'A{i}')
sampled = pd.concat(random_samples(4), ignore_index=True)
>>> sampled
ColumnA ColumnB Blocks Groups
0 A 12 1 A1
1 D 76 2 A1
2 I 76 3 A1
3 k 80 4 A1
4 n 67 5 A1
5 C 44 1 A2
6 G 65 2 A2
7 J 231 3 A2
8 l 55 4 A2
9 m 27 5 A2
10 B 32 1 A3
11 G 65 2 A3
12 H 87 3 A3
13 l 55 4 A3
14 m 27 5 A3
15 B 32 1 A4
16 F 123 2 A4
17 I 76 3 A4
18 l 55 4 A4
19 m 27 5 A4
在您的代码中 .sample(frac = 1)
returns 100% 的样本,即所有样本。你想要 .sample(n=1)
的版本,例如,如果你只想要一组,你会做
df.groupby('Blocks').apply(lambda x: x.sample(n=1, random_state=1234))
得到
ColumnA ColumnB Blocks
Blocks
1 0 A 12 1
2 3 D 76 2
3 7 H 87 3
4 10 k 80 4
5 12 m 27 5
例如,要获得 5 个组,您将使用 n=5
和 replace=True
(因为有些组的元素少于 5 个),然后重新排列:
df = df.groupby('Blocks').apply(lambda x: x.sample(n=5, replace = True, random_state=1234)).reset_index(drop = True)
df['Groups'] = 'A' + df.groupby('Blocks').cumcount().astype(str)
df.sort_values('Groups')
生产
ColumnA ColumnB Blocks Groups
-- --------- --------- -------- --------
0 C 44 1 A0
20 o 34 5 A0
5 G 65 2 A0
15 l 55 4 A0
10 J 231 3 A0
1 B 32 1 A1
21 n 67 5 A1
6 G 65 2 A1
16 l 55 4 A1
11 I 76 3 A1
22 m 27 5 A2
17 k 80 4 A2
12 H 87 3 A2
7 F 123 2 A2
2 A 12 1 A2
13 H 87 3 A3
8 E 99 2 A3
18 l 55 4 A3
3 A 12 1 A3
23 m 27 5 A3
14 H 87 3 A4
9 D 76 2 A4
19 k 80 4 A4
4 A 12 1 A4
24 m 27 5 A4
- 它确实不是随机的,但会根据需要分组
- 源数据帧的顺序将影响块分配给 Group 的顺序
df = pd.DataFrame({'ColumnA': ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'k', 'l', 'm', 'n', 'o'],
'ColumnB': [12, 32, 44, 76, 99, 123, 65, 87, 76, 231, 80, 55, 27, 67, 34],
'Blocks': [1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5]})
# generate a series that is "A{n}" where "n" is occurrence# of "Block"
sg = df.groupby("Blocks").apply(lambda g: pd.Series([f"A{i+1}"
for i in range(len(g))],name="Group")).explode().reset_index(drop=True)
df.join(sg)
ColumnA | ColumnB | Blocks | Group | |
---|---|---|---|---|
0 | A | 12 | 1 | A1 |
1 | B | 32 | 1 | A2 |
2 | C | 44 | 1 | A3 |
3 | D | 76 | 2 | A1 |
4 | E | 99 | 2 | A2 |
5 | F | 123 | 2 | A3 |
6 | G | 65 | 2 | A4 |
7 | H | 87 | 3 | A1 |
8 | I | 76 | 3 | A2 |
9 | J | 231 | 3 | A3 |
10 | k | 80 | 4 | A1 |
11 | l | 55 | 4 | A2 |
12 | m | 27 | 5 | A1 |
13 | n | 67 | 5 | A2 |
14 | o | 34 | 5 | A3 |