python - Python:numpy 的 random.choice() 的更快替代方案?
问题描述
我正在尝试对 0 到 999 之间的 1000 个数字进行采样,权重向量指示选择特定数字的概率:
import numpy as np
resampled_indices = np.random.choice(a = 1000, size = 1000, replace = True, p = weights)
不幸的是,这个过程必须在更大的 for 循环中运行数千次,这似乎np.random.choice
是该过程的主要速度瓶颈。因此,我想知道是否有任何方法可以加快速度np.random.choice
或使用产生相同结果的替代方法。
解决方案
您似乎可以通过使用统一采样然后使用“反转”累积分布来稍微快一点np.searchsorted
:
# assume arbitrary probabilities
weights = np.random.randn(1000)**2
weights /= weights.sum()
def weighted_random(w, n):
cumsum = np.cumsum(w)
rdm_unif = np.random.rand(n)
return np.searchsorted(cumsum, rdm_unif)
# first method
%timeit np.random.choice(a = 1000, size = 1000, replace = True, p = weights)
# 10000 loops, best of 3: 220 µs per loop
# proposed method
%timeit weighted_random(weights, n)
# 10000 loops, best of 3: 158 µs per loop
现在我们可以凭经验检查概率是否正确:
samples =np.empty((10000,1000),dtype=int)
for i in xrange(10000):
samples[i,:] = weighted_random(weights)
empirical = 1. * np.bincount(samples.flatten()) / samples.size
((empirical - weights)**2).max()
# 3.5e-09
推荐阅读
- python - 将图像分成块并比较每个对应的块
- python - 用 pybind11 包装 C++ 分配的实例
- type-conversion - 当 std_logic_vector 的大小可参数化时,如何计算它所需的位数?
- clojure - 如何使用实现 IReduceInit 的集合
- sql - 将特定行转换为列的 SQL 查询
- javascript - 将对象映射到接口并删除所有不存在的键
- javascript - 不同容器如何使用java脚本方法?
- android - 计划通知不适用于版本 8 和 9 的某些 android 设备
- django - 无法将关键字“模型”解析为字段。Django 过滤器
- javascript - 我们如何确定图像是否被 JavaScript 修改/操作