如何将含设备ID的DataFrame随机均分并标记A/B?
我来帮你搞定这个设备分组标记的问题!针对你的需求,我会先解决方法2的标记回原DataFrame的问题,再给你优化方法1让分组更接近均分:
方法2:用sample实现精准分组并标记回原表
你已经用sample选到了A组的4682478行,接下来只需要利用索引匹配就能轻松把标记加回去,步骤很简单:
- 先给原
devicesDataFrame新增Experiment列,默认设为"B" - 用选中的A组的索引,把对应行的
Experiment改成"A"
直接上代码:
# 随机选取50%的行作为A组,random_state固定可以让结果复现 a_group = devices.sample(frac=0.5, random_state=42) # 新增列,默认标记为B组 devices['Experiment'] = 'B' # 定位A组的行,修改标记为A devices.loc[a_group.index, 'Experiment'] = 'A'
这样操作后,A组正好是4682478行,B组是剩下的4682479行,差值只有1,完全符合你“尽可能均分”的要求。
方法1:优化自定义随机函数,实现极致均衡
你之前的自定义函数导致两组差值1111,应该是随机生成时没控制总数的均衡性。可以用下面的方法让分组完全精准:
- 先算出A组需要的行数:总行数整除2(9364957//2=4682478)
- 生成一个包含对应数量True和False的数组,再打乱顺序
- 用这个数组来标记A/B组
代码示例:
import numpy as np total_rows = len(devices) a_group_size = total_rows // 2 # 生成一个恰好有a_group_size个True的数组,然后打乱顺序 random_mask = np.random.permutation([True]*a_group_size + [False]*(total_rows - a_group_size)) # 根据标记数组赋值 devices['Experiment'] = np.where(random_mask, 'A', 'B')
这个方法能保证两组的行数差绝对是1(因为总行数是奇数),比你之前的自定义方法均衡太多了。
最后可以验证一下分组结果:
print(devices['Experiment'].value_counts()) # 输出会是: # B 4682479 # A 4682478 # Name: Experiment, dtype: int64
内容的提问来源于stack exchange,提问作者Samer Aamar
相关产品推荐
相关产品推荐

