Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/304.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 有效随机抽样_Python_Math_Random - Fatal编程技术网

Python 有效随机抽样

Python 有效随机抽样,python,math,random,Python,Math,Random,我的问题很简单: 我有一个有2000万个浮点数的数组。在该数组中,每个浮点数都有随机改变的概率p 最简单的方法是在数组中移动,执行if(rand(0,1)=0.5,无论做什么都不会节省很多时间,因为您仍然可能访问大多数元素。但是,如果p较低,您可以从n=20M的a和您确定要接触多少元素的概率中得出 In [23]: np.random.binomial(20*10**6, 0.1) Out[23]: 1999582 In [24]: np.random.binomial(20*10**6, 0

我的问题很简单: 我有一个有2000万个浮点数的数组。在该数组中,每个浮点数都有随机改变的概率p

最简单的方法是在数组中移动,执行if(rand(0,1) 然而,即使是并行化,它的速度也非常慢,我在想是否有一种更快的方法来随机获取一些要修改的索引

我的第一个想法是选取p*n随机数,其中n是数组中浮点数的总数,但是,这并不完全代表概率分布,因为在第一种情况下,没有任何东西可以保证只修改p*n浮点数

想法


PD:我正在使用python进行实现,可能以前有人遇到过这个问题,并在库中实现了一些东西,但我找不到它。

首先,如果p很高,即>=0.5,无论做什么都不会节省很多时间,因为您仍然可能访问大多数元素。但是,如果p较低,您可以从n=20M的a和您确定要接触多少元素的概率中得出

In [23]: np.random.binomial(20*10**6, 0.1)
Out[23]: 1999582

In [24]: np.random.binomial(20*10**6, 0.99999)
Out[24]: 19999801

In [25]: np.random.binomial(20*10**6, 0.5)
Out[25]: 10001202

In [26]: np.random.binomial(20*10**6, 0.0001)
Out[26]: 1986
[...]
In [30]: np.random.binomial(20*10**6, 0.0001)
Out[30]: 1989

In [31]: np.random.binomial(20*10**6, 0.0001)
Out[31]: 1988

这个数字是假设n次试验的成功次数,每次试验的成功几率为p,这正是您的情况。

首先,如果p很高,即>=0.5,无论您做什么,您都不会节省太多时间,因为您仍然可能访问大多数元素。但是,如果p较低,您可以从n=20M的a和您确定要接触多少元素的概率中得出

In [23]: np.random.binomial(20*10**6, 0.1)
Out[23]: 1999582

In [24]: np.random.binomial(20*10**6, 0.99999)
Out[24]: 19999801

In [25]: np.random.binomial(20*10**6, 0.5)
Out[25]: 10001202

In [26]: np.random.binomial(20*10**6, 0.0001)
Out[26]: 1986
[...]
In [30]: np.random.binomial(20*10**6, 0.0001)
Out[30]: 1989

In [31]: np.random.binomial(20*10**6, 0.0001)
Out[31]: 1988

这个数字是假设n次试验都有p次成功机会的成功次数,这正是您的情况。

您可以使用
[0,1)
中的值生成一个随机数组,该数组的大小与数据向量的大小相同
n

rnd = np.random.rand(n)
现在检查这些随机值小于
p

mask = rnd < p

或者使用您想要更改数据的任何方法。

您可以使用
[0,1)
中的值生成与数据向量大小相同的随机数组

rnd = np.random.rand(n)
现在检查这些随机值小于
p

mask = rnd < p
或者使用您想要更改数据的任何方法。

您的数组:

array = np.random.random(size=100) # Whatever
随机0/1的数组:

p = 0.05 # Could be an array itself
markers = np.random.binomial(1, p, array.shape[0])
要修改的值的索引数组:

locations = np.where(markers)[0]
# Something like array([19, 29, 32, 67, 68, 71])
您可以使用这些索引在原始数组中循环,或者使用类似于
array[locations]=…
的内容一次性修改所有值您的数组:

array = np.random.random(size=100) # Whatever
随机0/1的数组:

p = 0.05 # Could be an array itself
markers = np.random.binomial(1, p, array.shape[0])
要修改的值的索引数组:

locations = np.where(markers)[0]
# Something like array([19, 29, 32, 67, 68, 71])

您可以使用这些索引在原始数组中循环,或者使用类似于
数组[locations]=…
的方法一次修改所有值,这在我的机器上运行~4秒/轮

import random

rand = random.random
p = 0.1
TOTAL_ROUND = 10

x = [rand() for i in xrange(20000000)]

for i in range(TOTAL_ROUND):
    print "round", i
    x = [rand() if val < p else val for val in x]
随机导入
rand=random.random
p=0.1
总轮数=10
x=[rand()表示x范围内的i(20000000)]
对于范围内的i(整轮):
打印“圆形”,i
x=[rand()如果val
这在我的机器上运行约4秒/轮

import random

rand = random.random
p = 0.1
TOTAL_ROUND = 10

x = [rand() for i in xrange(20000000)]

for i in range(TOTAL_ROUND):
    print "round", i
    x = [rand() if val < p else val for val in x]
随机导入
rand=random.random
p=0.1
总轮数=10
x=[rand()表示x范围内的i(20000000)]
对于范围内的i(整轮):
打印“圆形”,i
x=[rand()如果val
如果p很小,可以通过使用
numpy.random.geometric
提供被修改元素之间距离的示例来节省大量时间

通过数组的简单过程:

from numpy.random import geometric

index = -1
while True:
  index += geometric(0.01)
  if index >= len(ary):
    break
  ary[ind] = # compute new value
Numpy分布函数可以生成一个返回值数组,因此只要p很小,一次生成所有步长值可能会更快:

from numpy import cumsum
from numpy.random import geometric

for index in cumsum(geometric(p, size=int(len(ary) * p * 1.1))):
  if index < len(ary):
    ary[index] = # compute new value
从numpy导入cumsum
从numpy.random导入几何体
对于以总和表示的索引(几何(p,size=int(len(ary)*p*1.1)):
如果索引

1.1是一个模糊因子,用于确保从几何分布中选择足够的样本。对于大型阵列,它应该是好的,但不能保证。更好的(尽管更复杂)解决方案是以块(比如10000块)的形式生成样本,并一直这样做,直到你到达数组的末尾。

如果p很小,你可以通过使用
numpy.random.geometric
来提供被改变元素之间距离的样本,从而节省大量时间

通过数组的简单过程:

from numpy.random import geometric

index = -1
while True:
  index += geometric(0.01)
  if index >= len(ary):
    break
  ary[ind] = # compute new value
Numpy分布函数可以生成一个返回值数组,因此只要p很小,一次生成所有步长值可能会更快:

from numpy import cumsum
from numpy.random import geometric

for index in cumsum(geometric(p, size=int(len(ary) * p * 1.1))):
  if index < len(ary):
    ary[index] = # compute new value
从numpy导入cumsum
从numpy.random导入几何体
对于以总和表示的索引(几何(p,size=int(len(ary)*p*1.1)):
如果索引

1.1是一个模糊因子,用于确保从几何分布中选择足够的样本。对于大型阵列,它应该是好的,但不能保证。更好的(尽管更复杂)解决方案是以块(例如10000块)的形式生成样本,并继续这样做,直到您能够到达数组的末尾。

是否
p
非常小?是的,p很小,0.01到0.1(1-10%的修改机会)@DyZ我认为这是为了生成随机数,对吗?我有一个现有的数组,比如说2000万个元素。每个元素都有被修改的概率p。我必须随机修改它们,最后的数组需要是一个2000万个元素的数组。未修改的元素将包含它们的旧值,而修改的元素将有一个新值随机生成一个新的。我可以使用np.random.choice(20000000,n,replace=False),然而,我仍然需要一种方法来正确计算n,而手动修改这些索引对所有数字来说都是一样的吗?此外,为了找到更有效的方法,你应该展示你现在正在做什么,例如,你正在使用循环、列表理解或numpy,以及如何使用?是的,
p
非常小吗?是的,p很小,0.01到0.1(1-10%的修改概率)@DyZ我想这是用来生成随机数的,对吧?我有一个EXI