Pandas:根据目标分布从 DataFrame 中采样

问题描述 投票:0回答:1

我有一个 Pandas DataFrame,其中包含从分布

D
中提取的实例数据集
x
x
可以说是均匀的,或者例如高斯的。

我想根据一些新的

n
D
中绘制
target_distribution
样本,这些新的
x
通常与

x

不同。我怎样才能有效地做到这一点?

现在,我对一个值 
D
、子集
x +- eps
进行采样,使其包含所有

x

以及从中提取的样本。但当数据集变大时,速度会非常慢。人们一定想出了更好的解决方案。也许解决方案已经很好,但可以更有效地实施?

我可以将 

import numpy as np import pandas as pd import numpy.random as rnd from matplotlib import pyplot as plt from tqdm import tqdm n_target = 30000 n_dataset = 100000 x_target_distribution = rnd.normal(size=n_target) # In reality this would be x_target_distribution = my_dataset["x"].sample(n_target, replace=True) df = pd.DataFrame({ 'instances': np.arange(n_dataset), 'x': rnd.uniform(-5, 5, size=n_dataset) }) plt.hist(df["x"], histtype="step", density=True) plt.hist(x_target_distribution, histtype="step", density=True) def sample_instance_with_x(x, eps=0.2): try: return df.loc[abs(df["x"] - x) < eps].sample(1) except ValueError: # fallback if no instance possible return df.sample(1) df_sampled_ = [sample_instance_with_x(x) for x in tqdm(x_target_distribution)] df_sampled = pd.concat(df_sampled_) plt.hist(df_sampled["x"], histtype="step", density=True) plt.hist(x_target_distribution, histtype="step", density=True)

分成层,这样会更快,但是没有这个有没有解决方案?

我当前的代码,工作正常,但速度很慢(30k/100k 需要 1 分钟,但我有 200k/700k 左右。)
python pandas sampling
1个回答
9
投票

不要生成新点并在 
np.random.choice
中查找最近邻点,而是定义应根据目标分布对每个点进行采样的概率。您可以使用
df.x
。对于如下所示的高斯目标分布,在一秒左右的时间内从

x = np.sort(df.x) f_x = np.gradient(x)*np.exp(-x**2/2) sample_probs = f_x/np.sum(f_x) samples = np.random.choice(x, p=sample_probs, size=1000000)
 采样一百万个点:

sample_probs

df.sample
是关键量,因为它可以连接回数据框或用作

# sample df rows without replacement df_samples = df["x"].sort_values().sample( n=1000, weights=sample_probs, replace=False, )
 的参数,例如:

plt.hist(samples, bins=100, density=True)

x = np.sort(np.random.normal(size=100000)) f_x = np.gradient(x)*np.ones(len(x)) sample_probs = f_x/np.sum(f_x) samples = np.random.choice(x, p=sample_probs, size=1000000)

的结果:

我们还可以尝试高斯分布x、均匀目标分布

D

如果我们增加垃圾箱的大小,尾巴会看起来更均匀;这是一个边缘稀疏的伪影。

评论

这种方法基本上计算对任何

x_i
进行采样的概率作为与
x
相关的
x_i
的跨度以及邻域中的概率密度:

prob(x_i) ~ delta_x*rho(x_i)

更稳健的处理方法是将

rho
整合到与每个
delta_x
相关的跨度
x_i
上。另请注意,如果忽略
delta_x
项,将会出现错误,如下所示。如果原始
x_i
没有近似均匀采样,情况会更糟:

© www.soinside.com 2019 - 2024. All rights reserved.