【问题标题】:Randomly select 50% of records from 3 different groups for A/B test从 3 个不同的组中随机选择 50% 的记录进行 A/B 测试
【发布时间】:2022-01-08 15:12:57
【问题描述】:

抱歉,如果这已经被问过了。我正在尝试设置一个小型 A/B 测试并将记录平均 (50%) 分成 3 个类别:Low intentMedium intentHigh intent。我想随机选择 3 个类别中的 50% 到对照组,50% 到治疗组到另一列。

样本数据:

|ID|Buyer Intent  |Email
:--:|:-----------:|:-------------|
|1  |Low Intent   |john@gmail.com|
|2  |Medium Intent|jane@gmail.com|
|3  |Medium Intent|tom@gmail.com |
|4  |Low Intent   |sara@gmail.com|
|5  |High Intent  |mich@gmail.com|
|6  |High Intent  |sall@gmail.com|

所需数据:

|ID|Buyer Intent |Email           |Group
:--|:-----------:|:--------------:|:----------:|
|1 |Low Intent   |john@gmail.com  |Control     |
|2 |Medium Intent|jane@gmail.com  |Treatment   |
|3 |Medium Intent|tom@gmail.com   |Control     |
|4 |Low Intent   |sara@gmail.com  |Treatment.  |
|5 |High Intent  |mich@gmail.com  |Treatment.  |
|6 |High Intent  |sall@gmail.com  | Control.   |

【问题讨论】:

  • 感谢您提供的数据。请以更易于复制和粘贴到程序中的格式提供,例如df.head().to_dict('list')

标签: python pandas dataframe numpy


【解决方案1】:

使用groupby.sample 选择每组50% 的记录,然后使用np.where 分配标签:

control = df.groupby('Buyer Intent').sample(frac=0.5).index

df['Group'] = np.where(df.index.isin(control), 'Control', 'Treatment')

#    ID   Buyer Intent           Email      Group
# 0   1     Low Intent  john@gmail.com    Control
# 1   2  Medium Intent  jane@gmail.com    Control
# 2   3  Medium Intent   tom@gmail.com  Treatment
# 3   4     Low Intent  sara@gmail.com  Treatment
# 4   5    High Intent  mich@gmail.com    Control
# 5   6    High Intent  sall@gmail.com  Treatment

注意groupby.sample 已经随机化了:

从每个组中返回一个随机项目样本。

但要显式随机播放,您可以添加DataFrame.samplefrac=1

# shuffle df
df = df.sample(frac=1)

# same as before
control = df.groupby('Buyer Intent').sample(frac=0.5).index
df['Group'] = np.where(df.index.isin(control), 'Control', 'Treatment')

如果你没有groupby.sample (pandas

  • 试试groupby.apply + DataFrame.sample

    control = df.groupby('Buyer Intent').apply(lambda g: g.sample(frac=0.5))
    df['Group'] = np.where(df.index.isin(control), 'Control', 'Treatment')
    
  • groupby.apply + np.random.choice:

    control = df.groupby('Buyer Intent').apply(lambda g: np.random.choice(g.index, int(len(g)/2)))
    df['Group'] = np.where(df.index.isin(control), 'Control', 'Treatment')
    

【讨论】:

  • 有没有办法随机选择。数据可能按某种顺序排列,我想确保该组是随机选择的。我可以使用 numpy.random.shuffle 吗?
  • 我看到 AttributeError: Cannot access callable attribute 'sample' of 'DataFrameGroupBy' objects,尝试使用 'apply' 方法。这里可能有什么工作?谢谢
  • @RyanDan 你的pd.__version__ 是什么? groupby.sample 是在 1.1.0 版(2020 年 7 月)中引入的,所以听起来你的版本比较旧。你能更新吗?
  • @RyanDan 我用groupby.apply 发布了一个解决方法,但我仍然建议尽可能更新
  • 是的。我能够更新熊猫并且最初的方式有效。谢谢
【解决方案2】:
  1. 要选择 50%,您必须使用从每个组中返回随机项目样本的东西,这个东西称为“groupby.sample”。

  2. 接下来你需要一些东西来根据条件返回选择的项目,这个东西叫做 np.where。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-02
    • 1970-01-01
    • 1970-01-01
    • 2012-12-22
    • 1970-01-01
    相关资源
    最近更新 更多