python – 随机矩阵的所有行的快速随机加权选择
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了python – 随机矩阵的所有行的快速随机加权选择,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含3276字,纯文字阅读大概需要5分钟。
内容图文
![python – 随机矩阵的所有行的快速随机加权选择](/upload/InfoBanner/zyjiaocheng/708/ce0be852333b4d70a70ef6a3f824c4a9.jpg)
numpy.random.choice允许从向量中加权选择,即
arr = numpy.array([1, 2, 3])
weights = numpy.array([0.2, 0.5, 0.3])
choice = numpy.random.choice(arr, p=weights)
选择1概率为0.2,2选择概率为0.5,3选择概率为0.3.
如果我们想以矢量化的方式快速完成2D阵列(矩阵),每个行都是概率向量,该怎么办?也就是说,我们想要一个随机矩阵的选择向量?这是超级慢的方式:
import numpy as np
m = 10
n = 100 # Or some very large number
items = np.arange(m)
prob_weights = np.random.rand(m, n)
prob_matrix = prob_weights / prob_weights.sum(axis=0, keepdims=True)
choices = np.zeros((n,))
# This is slow, because of the loop in Python
for i in range(n):
choices[i] = np.random.choice(items, p=prob_matrix[:,i])
打印(选择):
array([ 4., 7., 8., 1., 0., 4., 3., 7., 1., 5., 7., 5., 3.,
1., 9., 1., 1., 5., 9., 8., 2., 3., 2., 6., 4., 3.,
8., 4., 1., 1., 4., 0., 1., 8., 5., 3., 9., 9., 6.,
5., 4., 8., 4., 2., 4., 0., 3., 1., 2., 5., 9., 3.,
9., 9., 7., 9., 3., 9., 4., 8., 8., 7., 6., 4., 6.,
7., 9., 5., 0., 6., 1., 3., 3., 2., 4., 7., 0., 6.,
3., 5., 8., 0., 8., 3., 4., 5., 2., 2., 1., 1., 9.,
9., 4., 3., 3., 2., 8., 0., 6., 1.])
This post表明,cumsum和bisect可能是一种潜在的方法,并且速度很快.但是,虽然numpy.cumsum(arr,axis = 1)可以沿numpy数组的一个轴执行此操作,但bisect.bisect函数一次只能在单个数组上运行.同样,numpy.searchsorted也适用于1D阵列.
有没有一种快速方法只使用矢量化操作来做到这一点?
解决方法:
这是一个非常快速的完全矢量化版本:
def vectorized(prob_matrix, items):
s = prob_matrix.cumsum(axis=0)
r = np.random.rand(prob_matrix.shape[1])
k = (s < r).sum(axis=0)
return items[k]
理论上,搜索排序是用于在累积求和概率中查找随机值的正确函数,但是当m相对较小时,k =(s <r).sum(轴= (如果你的m实际上要大得多,你必须运行一些测试来看看在这个方法变慢之前m的大小.)="" 0)最终更快.它的时间复杂度为o(m),而搜索排序方法为o(log(m)),但这只会对更大的m有影响.此外,cumsum是o(m),因此矢量化和@="" 10000(使用原始函数并从@="" <="" =="" p="" perimosocordiae的改进都是o(m).="" perimosocordiae的答案改进):="" 这是我得到的时间m="10和n">
In [115]: %timeit original(prob_matrix, items)
1 loops, best of 3: 270 ms per loop
In [116]: %timeit improved(prob_matrix, items)
10 loops, best of 3: 24.9 ms per loop
In [117]: %timeit vectorized(prob_matrix, items)
1000 loops, best of 3: 1 ms per loop
定义函数的完整脚本是:
import numpy as np
def improved(prob_matrix, items):
# transpose here for better data locality later
cdf = np.cumsum(prob_matrix.T, axis=1)
# random numbers are expensive, so we'll get all of them at once
ridx = np.random.random(size=n)
# the one loop we can't avoid, made as simple as possible
idx = np.zeros(n, dtype=int)
for i, r in enumerate(ridx):
idx[i] = np.searchsorted(cdf[i], r)
# fancy indexing all at once is faster than indexing in a loop
return items[idx]
def original(prob_matrix, items):
choices = np.zeros((n,))
# This is slow, because of the loop in Python
for i in range(n):
choices[i] = np.random.choice(items, p=prob_matrix[:,i])
return choices
def vectorized(prob_matrix, items):
s = prob_matrix.cumsum(axis=0)
r = np.random.rand(prob_matrix.shape[1])
k = (s < r).sum(axis=0)
return items[k]
m = 10
n = 10000 # Or some very large number
items = np.arange(m)
prob_weights = np.random.rand(m, n)
prob_matrix = prob_weights / prob_weights.sum(axis=0, keepdims=True)
内容总结
以上是互联网集市为您收集整理的python – 随机矩阵的所有行的快速随机加权选择全部内容,希望文章能够帮你解决python – 随机矩阵的所有行的快速随机加权选择所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。