以相等的概率从 Pandas 组中随机选择 -- 意外行为
Randomly selecting from Pandas groups with equal probability -- unexpected behavior
我尝试从 12 个独特的组中随机抽样,每个组都有不同数量的观察值。我想从整个人口(数据框)中随机抽样,每组被选中的概率相同。最简单的示例是包含 2 个组的数据框。
groups probability
0 a 0.25
1 a 0.25
2 b 0.5
using np.random.choice(df['groups'], p=df['probability'], size=100)
每次迭代现在将有 50% 的机会选择 group a
和 50% 的机会选择 group b
为了得出概率,我使用了以下公式:
(1. / num_groups) / size_of_groups
或 Python:
num_groups = len(df['groups'].unique()) # 2
size_of_groups = df.groupby('label').size() # {a: 2, b: 1}
(1. / num_groups) / size_of_groups
哪个returns
groups
a 0.25
b 0.50
在我超过 10 个独特的组之前,这非常有效,之后我开始获得奇怪的分布。这是一个小例子:
np.random.seed(1234)
group_size = 12
groups = np.arange(group_size)
probs = np.random.uniform(size=group_size)
probs = probs / probs.sum()
g = np.random.choice(groups, size=10000, p=probs)
df = pd.DataFrame({'groups': g})
prob_map = ((1. / len(df['groups'].unique())) / df.groupby('groups').size()).to_dict()
df['probability'] = df['groups'].map(prob_map)
plt.hist(np.random.choice(df['groups'], p=df['probability'], size=10000, replace=True))
plt.xticks(np.arange(group_size))
plt.show()
我希望样本量足够大,分布相当均匀,但当组数超过 11 时,我得到了这些翅膀。如果我将 group_size
变量更改为 10 或更低,我会得到所需的均匀分布。
我不知道问题出在我计算概率的公式上,还是可能是浮点精度问题?任何人都知道完成此操作的更好方法或此示例的修复方法?
提前致谢!
您正在使用 hist
,默认为 10
个垃圾箱...
plt.rcParams['hist.bins']
10
传递 group_size
作为 bins
参数。
plt.hist(
np.random.choice(df['groups'], p=df['probability'], size=10000, replace=True),
bins=group_size)
你的计算没有问题。您得到的数组是:
arr = np.random.choice(df['groups'], p=df['probability'], size=10000, replace=True)
如果您检查值计数:
pd.Series(arr).value_counts().sort_index()
Out:
0 855
1 800
2 856
3 825
4 847
5 835
6 790
7 847
8 834
9 850
10 806
11 855
dtype: int64
它非常接近均匀分布。问题在于直方图的默认 bin 数 (10)。相反,试试这个:
bins = np.linspace(-0.5, 10.5, num=12)
pd.Series(arr).plot.hist(bins=bins)
我尝试从 12 个独特的组中随机抽样,每个组都有不同数量的观察值。我想从整个人口(数据框)中随机抽样,每组被选中的概率相同。最简单的示例是包含 2 个组的数据框。
groups probability
0 a 0.25
1 a 0.25
2 b 0.5
using np.random.choice(df['groups'], p=df['probability'], size=100)
每次迭代现在将有 50% 的机会选择 group a
和 50% 的机会选择 group b
为了得出概率,我使用了以下公式:
(1. / num_groups) / size_of_groups
或 Python:
num_groups = len(df['groups'].unique()) # 2
size_of_groups = df.groupby('label').size() # {a: 2, b: 1}
(1. / num_groups) / size_of_groups
哪个returns
groups
a 0.25
b 0.50
在我超过 10 个独特的组之前,这非常有效,之后我开始获得奇怪的分布。这是一个小例子:
np.random.seed(1234)
group_size = 12
groups = np.arange(group_size)
probs = np.random.uniform(size=group_size)
probs = probs / probs.sum()
g = np.random.choice(groups, size=10000, p=probs)
df = pd.DataFrame({'groups': g})
prob_map = ((1. / len(df['groups'].unique())) / df.groupby('groups').size()).to_dict()
df['probability'] = df['groups'].map(prob_map)
plt.hist(np.random.choice(df['groups'], p=df['probability'], size=10000, replace=True))
plt.xticks(np.arange(group_size))
plt.show()
我希望样本量足够大,分布相当均匀,但当组数超过 11 时,我得到了这些翅膀。如果我将 group_size
变量更改为 10 或更低,我会得到所需的均匀分布。
我不知道问题出在我计算概率的公式上,还是可能是浮点精度问题?任何人都知道完成此操作的更好方法或此示例的修复方法?
提前致谢!
您正在使用 hist
,默认为 10
个垃圾箱...
plt.rcParams['hist.bins']
10
传递 group_size
作为 bins
参数。
plt.hist(
np.random.choice(df['groups'], p=df['probability'], size=10000, replace=True),
bins=group_size)
你的计算没有问题。您得到的数组是:
arr = np.random.choice(df['groups'], p=df['probability'], size=10000, replace=True)
如果您检查值计数:
pd.Series(arr).value_counts().sort_index()
Out:
0 855
1 800
2 856
3 825
4 847
5 835
6 790
7 847
8 834
9 850
10 806
11 855
dtype: int64
它非常接近均匀分布。问题在于直方图的默认 bin 数 (10)。相反,试试这个:
bins = np.linspace(-0.5, 10.5, num=12)
pd.Series(arr).plot.hist(bins=bins)