gpt4 book ai didi

python - 如何在循环中每 x 个步骤创建一个新列表?

转载 作者:太空宇宙 更新时间:2023-11-03 21:39:12 25 4
gpt4 key购买 nike

我正在 python 上绘制一些随机游走函数并尝试创建它,以便它每 1000 步获取随机游走的位置,然后将它们绘制在直方图中。我意识到我可以每次为 n=1000,2000 等创建一个新列表,然后将步行的值附加到该列表中,但是有没有办法让 python 每 1000 步创建一个新列表?

import numpy as np 
import matplotlib.pyplot as plt

def random_walk(N,d):
walk = d*np.cumsum(2*np.random.binomial(1,.6,N)-1)
return walk
n1=[]
n2=[]
n3=[]
n4=[]
n5=[]

for k in range(5000):
particular_walk = random_walk(5000,2)
n1.append(particular_walk[1000])
n2.append(particular_walk[2000])
n3.append(particular_walk[3000])
n4.append(particular_walk[4000])
n5.append(particular_walk[-1])


plt.hist(n1,bins=20,histtype='step',density=True)
plt.hist(n2,bins=20,histtype='step',density=True)
plt.hist(n3,bins=20,histtype='step',density=True)
plt.hist(n4,bins=20,histtype='step',density=True)
plt.hist(n5,bins=20,histtype='step',density=True)
plt.show()

这是我到目前为止的代码,但我意识到它不起作用。我知道我可以有一个名为“中点”的列表,并将其设置为 2500 处特定步行的位置,但有没有办法自动执行此操作?

最佳答案

通常,在使用 numpy 时,您希望排除使用列表。数组在时间和空间上都更加高效。您还应该尽量避免使用显式的 Python 循环,因为 numpy 提供的矢量化速度会更快。

假设您想要对 Z 个不同的行走执行此操作,其中示例中的 Z = 5000,但您希望它在一般情况下更大。您可以利用大多数 numpy 函数都可以应用于特定轴的事实来完成此操作:

import numpy as np 
from matplotlib import pyplot as plt

Z = 5000
N = 5000
d = 2

all_walks = d * np.cumsum(2 * np.random.binomial(1, 0.6, size=(Z, N)) - 1, axis=1)

将步长设置为 (Z, N) 将为您提供一个包含 Z 行的矩阵,每行有 N 个步长。使用 axis=1 求累积和意味着对各列求和。现在每一行都是一个独立的行走。您可以使用非常基本的切片来获得您想要的任何列。第 n 列将包含每条 Z 步行的第 n 步。您想要将切片设为列的原因是这样绘图会变得更加容易。

让我们看一下n=1000:

n1k = all_walks[:, 1000]
plt.hist(n1k, bins=20, histtype='step', density=True)

到目前为止一切顺利。要每 1000 个样本进行一次,请使用索引中的步长:

n = 1000
samples = all_walks[:, n::n]

samples 现在是 Zx(N//n)-1 ((5000, 4)) 数组,其中包含索引 1000, 3000, 4000 处的步骤 在每个数组中。在这个例子中,您似乎想要总共五个样本。我认为,可以通过三种合理的方法来做到这一点:

  1. 从索引 0 开始:samples = all_walks[:,::n]
  2. 从索引 n-1 开始:samples = all_walks[:, n-1::n]
  3. 为您的步行添加额外的步骤(列):

    all_walks = ... size=(Z, N+1) ...
    samples = all_walks[:, n::n]

我不认为通过不一致地添加索引 -1 来扰乱间距是一个特别好的主意。我将使用选项#2(请记住索引 999 包含第 1000 步)。

好消息是 matplotlib 允许您一次性绘制向量的列:

plt.hist(samples, bins=20, histtype='step', density=True)

所以整个脚本实际上很短:

import numpy as np 
from matplotlib import pyplot as plt

Z = 5000
N = 5000
d = 2
n = 1000

all_walks = d * np.cumsum(2 * np.random.binomial(1, 0.6, size=(Z, N)) - 1, axis=1)
samples = all_walks[:, n-1::n]
plt.hist(samples, bins=20, histtype='step', density=True)
plt.show()

如果由于某种原因您无法同时在内存中保存大小为 Z * N 的 float 数组,您可以使用生成的循环来实现 all_walks 行一次走一步,有点像你最初尝试做的那样。请记住,只有当您将 Z 设置为一个非常大的数字或者由于某种原因没有 RAM 时才会出现这种情况:

samples = np.empty((Z, N//n))
for row in range(Z):
walk = d * np.cumsum(2 * np.random.binomial(1, 0.6, size=N) - 1)
samples[row] = walk[n-1::n]

如果您从相同的随机种子开始,两种方法都应该给出相同的结果。主要区别在于第一个需要更多内存,而第二个需要更多时间。

关于python - 如何在循环中每 x 个步骤创建一个新列表?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53008580/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com