从数据框中选择随机值而无需替换

时间:2018-09-30 22:32:07

标签: python pandas python-3.5

我正在听link的回答:

如果我的数据框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中随机选择的。即,如果查询为df.loc[(1, 1)],则应查找(1,1)的所有值,并从中随机选择一个要在上方显示的值。如果出现另一个df.loc[(1,1)],则应再次随机选择但不能替换。

我知道我需要修改代码以使用以下代码:

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

但不确定如何做。

编辑: 每次执行df.loc[(1, 1)]时,它都应该赋予新的价值,而无需更换。我打算多次进行df.loc[(1, 1)]。在上一个问题中,只有一次。

1 个答案:

答案 0 :(得分:1)

如果您尝试不替换而直接从数据集中进行采样,那么一次完成所有操作可能是有意义的,而不是迭代地从数据集中提取样本。

从每个月/日组合中抽取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