python - 起始值和最小值/最大值之间的随机游走序列

标签 python numpy random random-walk

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

这是我尝试这样做的尝试,但由于某些原因,有时该系列会超过最大值或低于最小值。似乎尊重开始和结束值,但不尊重最小值和最大值。这怎么能解决?我也想给出波动的标准偏差,但不知道如何给出。我使用 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")

最佳答案

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

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)

您可以将其视为几何问题的解决方案。 trend_line 连接您的 startend 点,并且有由 lower_boundupper_bound< 定义的边距rand 是您的随机游走,rand_trend 是趋势线,rand_deltas 是与 rand 趋势线的偏差。我们并置趋势线,并希望确保增量不超过边距。当 rand_deltas 超过允许的边距时,我们将超出部分“折叠”回边界。

最后,您将生成的随机增量添加到 start=>end 趋势线,从而获得所需的有界随机游走。

std 参数对应于随机游走的方差量。

更新:固定断言

在此版本中,“std”未 promise 为“间隔”。

关于python - 起始值和最小值/最大值之间的随机游走序列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46954510/

相关文章:

python - 如何将一个 python 字典附加到另一个,同时保留它们的键值?

python - numpy 从索引列表创建 3D 数组

python - 使用嵌套的 for 循环从 1 和 0 绘制棋盘

random - 从lua获取当前随机种子

unit-testing - Go 中的模拟随机生成器

Python & SQLite3 从两个表中选择

python - 使用Python 3.7.3,从给定目录中的文件加权列表中随机选择/选择

python - 在 Python 中加速一对多相关性计算

random - 网络标志 : How to make sure a variable stays in a defined range?

python - 绘制 OpenCV 轮廓并保存为透明图像