从数据框中选择随机值而不进行替换

Selecting random values from dataframe without replacement

我正在关注 的回答:

如果我有一个数据帧 df 为:

Month   Day     mnthShape
1      1    1.01
1      1    1.09
1      1    0.96
1      2    1.01
1      1    1.09
1      2    0.96
1      3    1.01
1      3    1.09
1      3    1.78

我想从 df 获得以下内容:

Month   Day mnthShape
1       1   1.01
1       2   1.01
1       1   0.96

其中 mnthShape 值是从索引 without replacement 中随机 select 编辑的。即,如果查询是 df.loc[(1, 1)],它应该从中随机查找 (1, 1) 和 select 的所有值,并在上面显示一个值。如果另一个 df.loc[(1,1)] 出现,它应该再次 select 随机但没有替换。

我知道我需要修改代码才能使用以下内容:

apply(np.random.choice, replace=False)

但不知道该怎么做。

编辑: 每次我做 df.loc[(1, 1)],它应该提供新的价值而不需要更换。我打算 df.loc[(1, 1)] 多次。在上一题中,只有一次。

如果您尝试在不替换的情况下从数据集中进行采样,那么一次完成所有操作可能比从数据集中反复提取样本更有意义。

从每个 month/day 组合中抽取 N 个样本需要有足够的组合来抽取 N 个样本而无需替换。但假设这是真的,您可以编写一个函数来从数据的子集中采样 N 个值:

def select_n(subset, n=2):
    choices = np.random.choice(len(x), size=n, replace=False)
    return (
        subset
        .mnthShape
        .iloc[choices]
        .reset_index(drop=True)
        .rename_axis('choice'))

将其应用于整个数据集:

In [34]: df.groupby(['Month', 'Day']).apply(select_n)
Out[34]:
choice        0     1
Month Day
1     1    1.09  0.96
      2    0.96  1.01
      3    1.09  1.01

如果您真的需要一次提取一个,您仍然需要一次生成所有样本以保证它们是在没有替换的情况下绘制的,但是您可以单独生成样本索引而不是子集数据:

In [48]: indices = np.random.choice(3, size=2, replace=False)

In [49]: df[((df.Month == 1) & (df.Day == 2))].iloc[indices[0]]
Out[49]:
Month        1.00
Day          2.00
mnthShape    1.01
Name: 3, dtype: float64

In [50]: df[((df.Month == 1) & (df.Day == 2))].iloc[indices[1]]
Out[50]:
Month        1.00
Day          2.00
mnthShape    0.96
Name: 5, dtype: float64