Python 开始-结束值之间以及最小/最大限制内的随机游动序列

Python 开始-结束值之间以及最小/最大限制内的随机游动序列,python,numpy,random,random-walk,Python,Numpy,Random,Random Walk,如何在起始值和结束值之间生成随机游动数据 不超过最大值,不低于最小值 这是我的尝试,但由于某些原因,有时序列会超过最大值或低于最小值。似乎尊重起始值和结束值,但不尊重最小值和最大值。如何解决这个问题?另外,我想给出波动的标准偏差,但不知道如何计算。我使用randomPerc表示波动,但这是错误的,因为我想指定std import numpy as np import matplotlib.pyplot as plt def generateRandomData(length,randomPer

如何在起始值和结束值之间生成随机游动数据 不超过最大值,不低于最小值

这是我的尝试,但由于某些原因,有时序列会超过最大值或低于最小值。似乎尊重起始值和结束值,但不尊重最小值和最大值。如何解决这个问题?另外,我想给出波动的标准偏差,但不知道如何计算。我使用
randomPerc
表示波动,但这是错误的,因为我想指定std

import numpy as np
import matplotlib.pyplot as plt

def generateRandomData(length,randomPerc, min,max,start, end):
    data_np = (np.random.random(length) - randomPerc).cumsum()
    data_np *= (max - min) / (data_np.max() - data_np.min())
    data_np += np.linspace(start - data_np[0], end - data_np[-1], len(data_np))
    return data_np

randomData=generateRandomData(length = 1000, randomPerc = 0.5, min = 50, max = 100, start = 66, end = 80)

## print values
print("Max Value",randomData.max())
print("Min Value",randomData.min())
print("Start Value",randomData[0])
print("End Value",randomData[-1])
print("Standard deviation",np.std(randomData))

## plot values
plt.figure()
plt.plot(range(randomData.shape[0]), randomData)
plt.show()
plt.close()
下面是一个简单的循环,用于检查序列是否低于最小值或超过最大值。这正是我试图避免的。该系列应分布在最小值和最大值的给定限值之间

 ## generate 1000 series and check if there are any values over the maximum limit or under the minimum limit
    for i in range(1000):
        randomData = generateRandomData(length = 1000, randomPerc = 0.5, min = 50, max = 100, start = 66, end = 80)
        if(randomData.min() < 50):
            print(i, "Value Lower than Min limit")
        if(randomData.max() > 100):
            print(i, "Value Higher than Max limit")
##生成1000系列,并检查是否有任何值超过最大限值或低于最小限值
对于范围(1000)内的i:
randomData=generateRandomData(长度=1000,randomPerc=0.5,最小=50,最大=100,开始=66,结束=80)
如果(randomData.min()<50):
打印(i,“值低于最小限值”)
如果(randomData.max()>100):
打印(i,“值高于最大限制”)

我注意到您使用内置函数作为参数(最小值和最大值),这是不推荐的(我将它们更改为最大值1和最小值1)。除此之外,您的代码应按预期工作:

def generateRandomData(length,randomPerc, min_1,max_1,start, end):
    data_np = (np.random.random(length) - randomPerc).cumsum()
    data_np *= (max_1 - min_1) / (data_np.max() - data_np.min())
    data_np += np.linspace(start - data_np[0], end - data_np[-1],len(data_np))
    return data_np
randomData=generateRandomData(1000, 0.5, 50, 100, 66, 80)
如果您愿意修改代码,这将起作用:

import random
for_fill=[]
# generate 1000 samples within the specified range and save them in for_fill
for x in range(1000):
    generate_rnd_df=random.uniform(50,100)
    for_fill.append(generate_rnd_df)
#set starting and end point manually
for_fill[0]=60
for_fill[999]=80

这里有一种方法,非常粗略地用代码表示

>>> import random
>>> steps = 1000
>>> start = 66
>>> end = 80
>>> step_size = (50,100)
生成1000个步骤,确保在所需范围内

>>> crude_walk_steps = [random.uniform(*step_size) for _ in range(steps)]
>>> import numpy as np
将这些步骤转化为步行,但请注意它们不符合要求

>>> crude_walk = np.cumsum(crude_walk_steps)
>>> min(crude_walk)
57.099056617839288
>>> max(crude_walk)
75048.948693623403
计算一个简单的线性变换以缩放步长

>>> from sympy import *
>>> var('a b')
(a, b)
>>> solve([57.099056617839288*a+b-66,75048.948693623403*a+b-80])
{b: 65.9893403510312, a: 0.000186686954219243}
>>> walk = [0.000186686954219243*_+65.9893403510312 for _ in crude_walk]
缩放台阶

>>> from sympy import *
>>> var('a b')
(a, b)
>>> solve([57.099056617839288*a+b-66,75048.948693623403*a+b-80])
{b: 65.9893403510312, a: 0.000186686954219243}
>>> walk = [0.000186686954219243*_+65.9893403510312 for _ in crude_walk]
验证行走现在是否在预期位置开始和停止

>>> min(walk)
65.999999999999986
>>> max(walk)
79.999999999999986

您还可以生成一个随机游动流,并过滤掉那些不符合您的约束的游动。只需注意,通过过滤,它们不再是真正的“随机”

下面的代码创建了无限的“有效”随机游动流。小心 约束非常严格,“下一个”调用可能需要一段时间;)


当你对你的行走施加条件时,它不能被认为是完全随机的。无论如何,一种方法是迭代地生成行走,并在每次迭代时检查边界。但如果您想要一个矢量化的解决方案,这里是:

def bounded_random_walk(length, lower_bound,  upper_bound, start, end, std):
    assert (lower_bound <= start and lower_bound <= end)
    assert (start <= upper_bound and end <= upper_bound)

    bounds = upper_bound - lower_bound

    rand = (std * (np.random.random(length) - 0.5)).cumsum()
    rand_trend = np.linspace(rand[0], rand[-1], length)
    rand_deltas = (rand - rand_trend)
    rand_deltas /= np.max([1, (rand_deltas.max()-rand_deltas.min())/bounds])

    trend_line = np.linspace(start, end, length)
    upper_bound_delta = upper_bound - trend_line
    lower_bound_delta = lower_bound - trend_line

    upper_slips_mask = (rand_deltas-upper_bound_delta) >= 0
    upper_deltas =  rand_deltas - upper_bound_delta
    rand_deltas[upper_slips_mask] = (upper_bound_delta - upper_deltas)[upper_slips_mask]

    lower_slips_mask = (lower_bound_delta-rand_deltas) >= 0
    lower_deltas =  lower_bound_delta - rand_deltas
    rand_deltas[lower_slips_mask] = (lower_bound_delta + lower_deltas)[lower_slips_mask]

    return trend_line + rand_deltas

randomData = bounded_random_walk(1000, lower_bound=50, upper_bound =100, start=50, end=100, std=10)
def-bounded_-random_-walk(长度、下限、上限、开始、结束、标准):

assert(下限哇…那个函数名真是太好了。你看过PEP指南吗?你应该让它们简短而有意义。嗯,好的,我会把它重命名为:)让我理解。在代码中,您希望生成1000个步骤的随机行走,从66步开始,到80步结束。步长应均匀分布在[50,100]上。什么是randomPerc
?是的,你是对的
randomPerc
是我试图定义它的波动程度,其范围在0.25和0.5之间。但是我想用标准差来代替,或者用0到1之间的百分比来代替。在我看来,你不可能得到所有的结果。如果将1000个均匀分布在[50100]上的步长相加,从66开始,到80结束的概率为零。Hei Xan,这一点不错,但如果在多次迭代中运行生成器,您会注意到它仍然会创建大于最大值或小于最小值的值。这正是我试图避免的
,对于范围(1000)内的i:randomData=generateRandomData(1000000,0.5,50,100,66,80),如果(randomData.min()<50):打印(“值低于限制”)elif(randomData.max()>100):打印(“值大于限制”)
我看到您编辑了答案,但我仍然不知道这是如何创建一个满足给定要求的随机游走序列的。比尔,我实现了解决方案,但没有得到我想要的结果,我只得到一条直线,没有y坐标。您误解了问题@RaduS想以一定的值开始行走,以值结束行走,并使行走保持在最小值和最大值之间。我想说的是,如果有足够多的人提供猜测,一个人会得到符合他想象的答案。就是这样,这正是我想要的,它是一个矢量化的。谢谢@igrinis您的解决方案太棒了:)最后一件事,当使用与开始和结束相同的较低和较高级别时,它会抛出一个错误。在某些情况下,最小和最大限制与开始和结束相同,并且序列most根本不会溢出。你会如何接近他们?有什么可以做的修改吗?这是可能的,但你们失去了对伪随机游动方差的控制。请参阅更新的代码。这非常完美,感谢您更新代码,这是一个非常棒的答案:)感谢您提供的解决方案:)