【问题标题】:Given a 2D Numpy array representing a 2D distribution, how to sample data from this distribution with the aid of Numpy or Scipy functions?给定一个表示二维分布的二维 Numpy 数组,如何借助 Numpy 或 Scipy 函数从该分布中采样数据?
【发布时间】:2019-09-24 19:05:39
【问题描述】:
给定一个形状为(200,200) 的二维numpy 数组dist,其中数组的每个条目表示所有x1 的(x1, x2) 的联合概率,x2 ∈ {0, 1, . . . , 199}。如何借助 Numpy 或 Scipy API 从该概率分布中采样二元数据 x = (x1, x2)?
【问题讨论】:
标签:
python
arrays
python-3.x
numpy
scipy
【解决方案1】:
此解决方案适用于任意维数的概率分布,假设它们是有效的概率分布(其内容必须总和为 1,等等)。它使分布变平,从中采样,并调整随机索引以匹配原始数组形状。
# Create a flat copy of the array
flat = array.flatten()
# Then, sample an index from the 1D array with the
# probability distribution from the original array
sample_index = np.random.choice(a=flat.size, p=flat)
# Take this index and adjust it so it matches the original array
adjusted_index = np.unravel_index(sample_index, array.shape)
print(adjusted_index)
另外,要获取多个样本,请在 np.random.choice 调用中添加 size 关键字参数,并在打印之前修改 adjusted_index:
adjusted_index = np.array(zip(*adjusted_index))
这是必要的,因为带有size 参数的np.random.choice 会输出每个坐标维度的索引列表,因此这会将它们压缩到坐标元组列表中。这也比简单地重复第一个代码更有效率。
相关文档:
【解决方案2】:
这是一种方法,但我确信使用 scipy 有一个更优雅的解决方案。
numpy.random 不处理 2d pmfs,所以你必须做一些重塑体操才能走这条路。
import numpy as np
# construct a toy joint pmf
dist=np.random.random(size=(200,200)) # here's your joint pmf
dist/=dist.sum() # it has to be normalized
# generate the set of all x,y pairs represented by the pmf
pairs=np.indices(dimensions=(200,200)).T # here are all of the x,y pairs
# make n random selections from the flattened pmf without replacement
# whether you want replacement depends on your application
n=50
inds=np.random.choice(np.arange(200**2),p=dist.reshape(-1),size=n,replace=False)
# inds is the set of n randomly chosen indicies into the flattened dist array...
# therefore the random x,y selections
# come from selecting the associated elements
# from the flattened pairs array
selections = pairs.reshape(-1,2)[inds]
【解决方案3】:
我无法发表评论,但要改进 kevinkayaks 的答案:
pairs=np.indices(dimensions=(200,200)).T
selections = pairs.reshape(-1,2)[inds]
不需要的可以替换为:
np.array([inds//m, inds%m]).T
不再需要矩阵“对”。