从 Matlab 到 Python 的一维随机游走 [英] 1D Random Walk from Matlab to Python

查看:66
本文介绍了从 Matlab 到 Python 的一维随机游走的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个Matlab代码,可以生成一维随机游动.

I have a Matlab code that generates a 1D random walk.

%% probability to move up or down
prob = [0.05, 0.95];

start = 2;  %% start with 2
positions(1) = start; 

for i=2:1000 
    rr = rand(1); 
    down = rr<prob(1) & positions(i-1)>1;  
    up = rr>prob(2) & positions(i-1)<4;  
    positions(i) = positions(i-1)-down + up; 
figure(1), clf
plot(positions)

这给了我下面的图使用Matlab进行1D随机游走

我需要尝试用Python进行翻译,而我想出了这个(使用numpy):

I need to try to translate this in Python and I have came up with this (using numpy):

import random
import numpy as np
import matplotlib.pyplot as plt

prob = [0.05, 0.95]  ##probability to move up or down
N = 100 ##length of walk

def randomWalk(N):
    positions=np.zeros(N)
    start = 2 ##Start at 2
    positions[0] = start
    for i in range(1,100):
        rr = random.randint(0,1)

        if rr<prob[0] and positions[i-1]>1: 
            start -= 1
        elif rr>prob[1] and positions[i-1]<4:
            start += 1
        positions[i] = start
    return positions

plt.plot(randomWalk(N))
plt.show()

它看起来与我想要的非常接近(请参见下图):使用Python的1D随机游动

It looks fairly close to what I want (see figure below):1D Random Walk with Python

但是我想知道它们是否真的等效,因为它们看起来确实不同:Python代码看起来比Matlab代码更尖锐.

But I wonder if they are really equivalent, because they do seem different: The Python code seems spikier than the Matlab one.

我的Python代码中缺少什么来实现完美的逐步增加/减少(类似于Matlab代码)?除非满足两个条件,否则它可能需要一个"else"来告诉它保持不变.我该如何实现?

What is missing in my Python code to achieve the perfect stepwise increase/decrease (similar to the Matlab code)? Maybe it needs an "else" that tells it to stay the same unless the two conditions are met. How do I implement that?

推荐答案

您所做的事情有很多不同.

You are doing a bunch of things differently.

对于其中之一,您使用的是MATLAB中的 rand ,它会返回0到1之间的一个随机浮点数..您正在执行 randint(0,1),这意味着从0到1的随机整数,不包括0".因此它将始终为1.您需要 random.random(),它返回介于0和1之间的随机浮点数.

For one, you are using rand in MATLAB, which returns a random float between 0 and 1. In python, you are using randint, which returns a random integer. You are doing randint(0, 1), which means "a random integer from 0 to 1, not including 0". So it will always be 1. You want random.random(), which returns a random float between 0 and 1.

接下来,您正在MATLAB中计算 down up ,但是在Python中,您正在计算 down up (在Python中).对于您的概率的特定情况,这些结果最终具有相同的结果,但是在语法上是不同的.在这种情况下,您可以使用与MATLAB几乎相同的语法.

Next, you are computing down and up in MATLAB, but in Python you are computing down or up in Python. For your particular case of probabilities these end up having the same result, but they are syntactically different. You can use an almost identical syntax to MATLAB for Python in this case.

最后,您为MATLAB计算的样本比Python多得多(大约多10倍).

Finally, you are calculating a lot more samples for MATLAB than Python (about a factor of 10 more).

这是您的MATLAB代码到Python的直接端口.对我来说,结果与您的MATLAB示例几乎相同(当然,具有不同的随机数):

Here is a direct port of your MATLAB code to Python. The result for me is pretty much the same as your MATLAB example (with different random numbers, of course):

import random
import matplotlib.pyplot as plt

prob = [0.05, 0.95]  # Probability to move up or down

start = 2  #Start at 2
positions = [start]

for _ in range(1, 1000):
    rr = random.random()
    down = rr < prob[0] and positions[-1] > 1
    up = rr > prob[1] and positions[-1] < 4
    positions.append(positions[-1] - down + up)

plt.plot(positions)
plt.show()

如果速度是一个问题,您可以使用 np.random.random(1000)提前生成随机数,并提前进行概率比较,从而加快速度以向量化的方式.

If speed is an issue you can probably speed this up by using np.random.random(1000) to generate the random numbers up-front, and do the probability comparisons up-front as well in a vectorized manner.

是这样的:

import random
import numpy as np
import matplotlib.pyplot as plt

prob = [0.05, 0.95]  # Probability to move up or down

start = 2  #Start at 2
positions = [start]

rr = np.random.random(1000)
downp = rr < prob[0]
upp = rr > prob[1]

for idownp, iupp in zip(downp, upp):
    down = idownp and positions[-1] > 1
    up = iupp and positions[-1] < 4
    positions.append(positions[-1] - down + up)

plt.plot(positions)
plt.show()

为了更多地解释第二个示例,基本上我正在做的是预先计算每个步骤的概率是低于第一个阈值还是高于第二个阈值.这比计算随机样本并在循环的每个步骤进行比较要快得多.然后,我使用 zip 将这两个随机序列组合为一个序列,其中每个元素都是来自两个序列的一对对应元素.这是假设使用python 3,如果您使用的是python 2,则应使用 itertools.izip 而不是 zip .

To explain a bit more about the second example, basically what I am doing is pre-computing whether the probability is below the first threshold or above the second for every step ahead of time. This is much faster than computing a random sample and doing the comparison at each step of the loop. Then I am using zip to combine those two random sequences into one sequence where each element is the pair of corresponding elements from the two sequences. This is assuming python 3, if you are using python 2 you should use itertools.izip instead of zip.

因此大致相当于:

import random
import numpy as np
import matplotlib.pyplot as plt

prob = [0.05, 0.95]  # Probability to move up or down

start = 2  #Start at 2
positions = [start]

rr = np.random.random(1000)
downp = rr < prob[0]
upp = rr > prob[1]

for i in range(len(rr)):
    idownp = downp[i]
    iupp = upp[i]
    down = idownp and positions[-1] > 1
    up = iupp and positions[-1] < 4
    positions.append(positions[-1] - down + up)

plt.plot(positions)
plt.show()

在python中,通常优选遍历值而不是索引.几乎从来没有需要迭代索引的情况.如果您发现自己在range(len(foo)):中为我做类似的事情,或者与之等效的事情,则几乎肯定是在做错什么.您应该直接在 foo 上进行迭代,或者如果您需要索引用于其他内容,则可以在iumerate(foo):中使用类似的方法,这样可以使您foo的元素及其索引.

In python, it is generally preferred to iterate over values, rather than indexes. There is pretty much never a situation where you need to iterate over an index. If you find yourself doing something like for i in range(len(foo)):, or something equivalent to that, you are almost certainly doing something wrong. You should either iterate over foo directly, or if you need the index for something else you can use something like for i, ifoo in enumerate(foo):, which gets you both the elements of foo and their indexes.

由于MATLAB语言中的各种限制,索引迭代在MATLAB中很常见.从技术上讲,可以做一些类似于我在MATLAB中的Python示例中所做的事情,但是在MATLAB中,它需要很多样板才能保证安全,并且在大多数情况下会非常慢.但是,在Python中,这是最快,最简洁的方法.

Iterating over indexes is common in MATLAB because of various limitations in the MATLAB language. It is technically possible to do something similar to what I did in that Python example in MATLAB, but in MATLAB it requires a lot of boilerplate to be safe and will be extremely slow in most cases. In Python, however, it is the fastest and cleanest approach.

这篇关于从 Matlab 到 Python 的一维随机游走的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆