startend值之间且在最小/最大限制内的随机游走序列

2024-09-30 01:34:53 发布

您现在位置:Python中文网/ 问答频道 /正文

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

这是我的尝试,但由于某些原因,有时序列会超过最大值或低于最小值。似乎开始值和结束值是被尊重的,但不是最小值和最大值。如何解决这个问题?另外,我想给出波动的标准差,但不知道如何计算。我使用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()

这是一个简单的循环,它检查序列是否低于最小值或超过最大值。这正是我要避免的。序列应分布在最小值和最大值的给定限值之间。在

^{pr2}$

Tags: importdatavaluenpplt序列minstart
3条回答

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

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连接着你的start和{}点,并有由lower_bound和{定义的边距。rand是你的随机游走,rand_trend是趋势线,rand_deltas是与{}趋势线的偏差。我们配置了趋势线,并希望确保三角洲不会超过利润。当rand_deltas超过允许的边距时,我们将多余的“折叠”回边界。在

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

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

更新:修复了断言

在这个版本中“std”不保证是“interval”。在

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

>>> import random
>>> steps = 1000
>>> start = 66
>>> end = 80
>>> step_size = (50,100)

生成1000步,确保在所需范围内。在

^{pr2}$

将这些步骤转换为步行,但请注意它们不符合要求。在

>>> 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]

验证漫游现在开始并在预期位置停止。在

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

我注意到您使用了内置函数作为参数(min和max),这是不可重复的(我将它们改为max_1和min_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)

如果您愿意修改您的代码,这将起作用:

^{pr2}$

相关问题 更多 >

    热门问题