Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/338.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_Numpy_Random - Fatal编程技术网

Python 生成复制任意分布的随机数

Python 生成复制任意分布的随机数,python,numpy,random,Python,Numpy,Random,我的数据中有一个变量z,它包含大约4000个值(从0.0到1.0),其直方图如下所示 现在我需要生成一个随机变量,称之为random_z,它应该复制上述分布 到目前为止,我尝试的是生成一个以1.0为中心的正态分布,这样我就可以删除所有高于1.0的分布,得到一个类似的分布。我一直在使用numpy.random.normal,但问题是我无法将范围设置为0.0到1.0,因为通常正态分布的平均值为0.0,标准偏差为1.0 用Python生成这个发行版还有其他方法吗 使用时,可以传递关键字参数来设置返回

我的数据中有一个变量
z
,它包含大约4000个值(从0.0到1.0),其直方图如下所示

现在我需要生成一个随机变量,称之为
random_z
,它应该复制上述分布

到目前为止,我尝试的是生成一个以1.0为中心的正态分布,这样我就可以删除所有高于1.0的分布,得到一个类似的分布。我一直在使用
numpy.random.normal
,但问题是我无法将范围设置为0.0到1.0,因为通常正态分布的平均值为0.0,标准偏差为1.0

用Python生成这个发行版还有其他方法吗

使用时,可以传递关键字参数来设置返回数组的平均值和标准偏差。这些关键字参数是
loc
(平均值)和
scale
(标准值)

将numpy导入为np
将matplotlib.pyplot作为plt导入
N=4000
平均值=1.0
标准=0.5
x=[]
而len(x)如果0.0如果您想要引导,您可以在观察到的序列上使用
random.choice()

在这里,我假设您希望平滑一点,而不关心生成新的极值

使用
pandas.Series.quantile()
和统一的[0,1]随机数生成器,如下所示

训练

  • 将您的随机样本放入熊猫系列,称此系列为
    S
生产

  • 以通常的方式在0.0和1.0之间生成一个随机数
    u
    ,例如。,
    random.random()
  • 返回
    S.分位数(u)
  • 如果您更愿意使用
    numpy
    而不是
    pandas
    ,从快速阅读中可以看出,您可以在步骤2中进行替换

    操作原则:

    从样本S中,
    pandas.series.quantile()
    numpy.percentile()
    用于计算方法的逆累积分布函数。分位数或百分位函数(相对于S)将均匀[0,1]伪随机数转换为具有样本S范围和分布的伪随机数

    简单示例代码 如果您需要最小化编码,并且不想编写和使用只返回单个实现的函数,那么它似乎是
    numpy.percentile
    bests
    pandas.Series.quantile

    让我们做一个预先存在的样本

    u将是新的统一随机数

    newR将是从S型分布中提取的新随机数

    >>> import numpy as np
    
    我需要一个要复制的随机数样本放入
    S

    为了创建一个示例,我将把一些统一的[0,1]随机数提高到三次方,并称之为sample
    S
    。通过选择以这种方式生成示例样本,我将提前知道——从平均值等于(x^3)(dx)从0到1的定积分——S的平均值应该是
    1/(3+1)
    =
    1/4
    =
    0.25

    在应用程序中,您可能需要执行其他操作,例如读取文件,以 创建一个numpy数组
    S
    ,其中包含要复制其分布的数据样本

    >>> S = pow(np.random.random(1000),3)  # S will be 1000 samples of a power distribution
    
    在此,我将检查S的平均值是否为0.25,如上所述

    >>> S.mean()
    0.25296623781420458 # OK
    
    获取最小值和最大值以显示np.percentile的工作原理

    >>> S.min()
    6.1091277680105382e-10
    >>> S.max()
    0.99608676594692624
    
    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()
    
    因为它会出错,u的刻度是0-1,需要0-100

    这将有助于:

    >>> newR = np.percentile(S, (100*u).tolist()) 
    
    这可以正常工作,但如果想要返回numpy数组,可能需要调整其类型

    >>> type(newR)
    <type 'list'>
    
    >>> newR = np.array(newR)
    

    您可以使用拒绝采样:您生成0的成对(z,y),如果您可以近似分布的累积密度函数(例如,通过获取直方图的累积和),则从该分布进行采样变得微不足道

    Sample uniformly p in interval [0.0,1.0]
    Lookup the value of x at which cdf(x) == p
    

    我想这基本上就是熊猫问题的答案。

    它必须如何密切跟踪分布?你能使用一阶近似,从z=0..0.5线性上升,然后从z=0.5..1.0平缓上升吗?它不需要精确地遵循这个分布,只需要稍微相似。我想,既然从0.5到1.0之间似乎有一个平缓,你就在问这个问题。嗯,可能是这样。但我的想法是取正态分布的一半,这样它几乎可以复制上面的。。。在LHS上是三角形分布,在RHS上是均匀分布?必须有99种不同的建模方法,你需要告诉我们的是你需要多大的精度?完美的解决方案,正是我想要的!想知道y=np.random.normal(loc=mean,scale=std,size=1)[0]中的[0]代表什么?
    y=np.random.normal(loc=mean,scale=std,size=1)
    返回一个大小为1的数组,所以我只是删除了要附加到列表中的第一个(0)值。否则,您将附加4000个numpy数组,每个数组包含1个元素。OP的数据看起来远不像正态分布的一段。请注意,它在0.5和1之间是双峰的,并且您建议的正常解决方案返回了太多接近0的值。考虑到4000个观测值,任何合适的拟合优度检验几乎肯定会拒绝你的数据和原始数据来自同一分布的假设。建议使用引导或分位数是一种更好的方法。@pjs你说得对,它们看起来不一样。当然,我选择了
    mean
    std
    的任意值,这可能会影响较低值的水平,但形状不同。然而,OP表示,他们自己一直在尝试使用这种方法,但未能使其发挥作用。因此,我提供了一个
    >>> type(newR)
    <type 'list'>
    
    >>> newR = np.array(newR)
    
    >>> newR.mean()
    0.25549728059744525 # close enough
    
    Sample uniformly p in interval [0.0,1.0]
    Lookup the value of x at which cdf(x) == p