The*_*tor 14 python random numpy
我有数据,其中我有一个变量z
,包含大约4000个值(从0.0到1.0),直方图看起来像这样.
现在我需要生成一个随机变量,调用它random_z
应该复制上面的分布.
到目前为止,我所尝试的是生成一个以1.0为中心的正态分布,这样我就可以删除1.0以上的所有内容,以获得类似的分布.我一直在使用numpy.random.normal
但问题是我无法将范围设置为0.0到1.0,因为通常正态分布的均值= 0.0且std dev = 1.0.
还有另一种方法可以在Python中生成此分发吗?
如果你想引导你可以使用random.choice()
你观察到的系列.
在这里,我假设你想要比平滑更多,你不关心产生新的极值.
使用pandas.Series.quantile()
和统一的[0,1]随机数发生器,如下所示.
训练
S
生产
u
以通常的方式生成介于0.0和1.0之间的随机数,例如,
random.random()
S.quantile(u)
如果你想用numpy
比pandas
,从快速阅读,它看起来像您可以替换numpy.percentile()
在步骤2中.
工作原理:
从样本S,pandas.series.quantile()
或numpy.percentile()
用于计算逆变换采样方法的逆累积分布函数.分位数或百分位数函数(相对于S)将均匀的[0,1]伪随机数转换为具有样本S的范围和分布的伪随机数.
如果您需要最小化编码并且不想编写和使用仅返回单个实现的函数,那么它似乎是numpy.percentile
最好的pandas.Series.quantile
.
设S是预先存在的样本.
你将是新的统一随机数
newR将是从S-like分布中提取的新randoms.
>>> import numpy as np
Run Code Online (Sandbox Code Playgroud)
我需要一个可以复制的随机数的样本S
.
为了创建一个例子,我将把一些统一的[0,1]随机数提升到第三个幂并调用该样本S
.通过选择以这种方式生成示例样本,我将事先知道 - 从平均值等于从0到1评估的(x ^ 3)(dx)的定积分 - S的平均值应该是1/(3+1)
= 1/4
=0.25
在您的应用程序中,您需要执行其他操作(可能是读取文件)来创建S
包含要复制其分布的数据样本的numpy数组.
>>> S = pow(np.random.random(1000),3) # S will be 1000 samples of a power distribution
Run Code Online (Sandbox Code Playgroud)
在这里,我将检查S的平均值是如上所述的0.25.
>>> S.mean()
0.25296623781420458 # OK
Run Code Online (Sandbox Code Playgroud)
得到最小值和最大值只是为了说明np.percentile是如何工作的
>>> S.min()
6.1091277680105382e-10
>>> S.max()
0.99608676594692624
Run Code Online (Sandbox Code Playgroud)
numpy.percentile函数将0-100映射到S的范围.
>>> np.percentile(S,0) # this should match the min of S
6.1091277680105382e-10 # and it does
>>> np.percentile(S,100) # this should match the max of S
0.99608676594692624 # and it does
>>> np.percentile(S,[0,100]) # this should send back an array with both min, max
[6.1091277680105382e-10, 0.99608676594692624] # and it does
>>> np.percentile(S,np.array([0,100])) # but this doesn't....
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python2.7/dist-packages/numpy/lib/function_base.py", line 2803, in percentile
if q == 0:
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
Run Code Online (Sandbox Code Playgroud)
如果我们生成100个新值,从制服开始,这不是很好:
>>> u = np.random.random(100)
Run Code Online (Sandbox Code Playgroud)
因为它会出错,并且u的比例为0-1,需要0-100.
这将有效:
>>> newR = np.percentile(S, (100*u).tolist())
Run Code Online (Sandbox Code Playgroud)
哪个工作正常,但如果你想要一个numpy数组,可能需要调整它的类型
>>> type(newR)
<type 'list'>
>>> newR = np.array(newR)
Run Code Online (Sandbox Code Playgroud)
现在我们有一个numpy数组.我们来检查新随机值的平均值.
>>> newR.mean()
0.25549728059744525 # close enough
Run Code Online (Sandbox Code Playgroud)
使用时,numpy.random.normal
您可以传递关键字参数来设置返回数组的均值和标准差.这些关键字参数是loc
(mean)和scale
(std).
import numpy as np
import matplotlib.pyplot as plt
N = 4000
mean = 1.0
std = 0.5
x = []
while len(x) < N:
y = np.random.normal(loc=mean, scale=std, size=1)[0]
if 0.0 <= y <= 1.0:
x.append(y)
plt.hist(x)
plt.show()
Run Code Online (Sandbox Code Playgroud)
如果您可以近似分布的累积密度函数(例如通过采用直方图的cumsum),那么从该分布中取样变得微不足道.
Sample uniformly p in interval [0.0,1.0]
Lookup the value of x at which cdf(x) == p
Run Code Online (Sandbox Code Playgroud)
我想这实际上是熊猫正在做的答案.