假设我有以下数据帧:
Type Name
S2019 John
S2019 Stephane
S2019 Mike
S2019 Hamid
S2021 Rahim
S2021 Ahamed
我想根据"类型"对数据集进行分组。然后添加一个名为"Sampled"然后在每一行随机添加"是"/"否","是"/"否"应该均匀分布。期望的数据帧可以是:
Type Name Sampled
S2019 John no
S2019 Stephane yes
S2019 Mike yes
S2019 Hamid no
S2021 Rahim yes
S2021 Ahamed no
您可以使用numpy.random.choice
:
import numpy as np
df['Sampled'] = np.random.choice(['yes', 'no'], size=len(df))
输出:
Type Name Sampled
0 S2019 John no
1 S2019 Stephane no
2 S2019 Mike yes
3 S2019 Hamid no
4 S2021 Rahim no
5 S2021 Ahamed yes
组间概率相等:
df['Sampled'] = (df.groupby('Type')['Type']
.transform(lambda g: np.random.choice(['yes', 'no'],
size=len(g)))
)
对于每个组,获得任意列(这里是Type,但没关系,这只是有一个形状为1),并应用np.random.choice
与组的长度作为参数。这将给出与组中具有相同概率的项目数量相同的"是"或"否"(注意,如果您愿意,您可以定义每个项目的特定概率)。
NB。不的概率相等吗?意思是你会得到50/50的肯定/否定,如果这是你想要的,请澄清
每组有一半是/否
如果您想要每种类型的一半(是/否)(奇数大小的情况下±1),您可以随机选择一半的索引。
idx = df.groupby('Type', group_keys=False).apply(lambda g: g.sample(n=len(g)//2)).index
df['Sampled'] = np.where(df.index.isin(idx), 'yes', 'no')
NB。如果是奇数,则np.where
函数中定义的第二项将多一个,这里"no"
分配相等数量的元素:
这将在多重性的极限下均匀分布。这意味着,对于3个元素和4个位置,将有两个a,一个b,一个c按随机顺序排列。如果您希望随机选择额外的项,请首先对输入进行洗牌。
elem = ['a', 'b', 'c']
df['Sampled'] = (df
.groupby('Type', group_keys=False)['Type']
.transform(lambda g: np.random.choice(np.tile(elem, int(np.ceil(len(g)/len(elem))))[:len(g)],
size=len(g), replace=False))
)
输出:
Type Name Sampled
0 S2019 John a
1 S2019 Stephane a
2 S2019 Mike b
3 S2019 Hamid c
4 S2021 Rahim a
5 S2021 Ahamed b
在GroupBy.transform
中使用自定义函数,并按等分布的值yes, no
创建辅助数组arr
,然后按numpy.random.shuffle
随机排序:
def f(x):
arr = np.full(len(x), ['no'], dtype=object)
arr[:int(len(x) * 0.5)] = 'yes'
np.random.shuffle(arr)
return arr
df['Sampled'] = df.groupby('Type')['Name'].transform(f)
print (df)
Type Name Sampled
0 S2019 John yes
1 S2019 Stephane no
2 S2019 Mike no
3 S2019 Hamid yes
4 S2021 Rahim no
5 S2021 Ahamed yes