【问题标题】:How to efficiently generate a straight line with random slope and intercept in Python?如何在 Python 中有效地生成具有随机斜率和截距的直线?
【发布时间】:2014-10-14 19:04:11
【问题描述】:

考虑一个非常基本的直线 y = m * x + b 的蒙特卡罗模拟,例如可视化参数mb 中不确定性的影响。 mb 都是从正态分布中采样的。来自 MATLAB 背景,我会将其写为

import numpy as np
import matplotlib.pyplot as plt

x = np.arange(start=0, stop=5, step=0.1)

n_data = len(x)
n_rnd = 1000

m = np.random.normal(loc=1, scale=0.3, size=n_rnd) 
b = np.random.normal(loc=5, scale=0.3, size=n_rnd)

y = np.zeros((n_data, n_rnd))  # pre-allocate y

for realization in xrange(n_rnd):
    y[:,realization] = m[realization] * x + b[realization]

plt.plot(x, y, "k", alpha=0.05);

这确实产生了所需的输出,但我觉得必须有一种更“Pythonic”的方式来做到这一点。我错了吗?如果没有,谁能给我一些代码示例,说明如何更有效地做到这一点?

举一个我正在寻找的例子:在 MATLAB 中,这可以很容易地在没有循环的情况下使用 bsxfun() 编写。在 Python 中是否有类似的东西,或者甚至是类似的东西的包?

【问题讨论】:

    标签: python numpy random montecarlo


    【解决方案1】:

    您可以使用numpy array broadcasting 一步创建您的y 数组,如下所示。

    import numpy as np
    import matplotlib.pyplot as plt
    
    x = np.arange(start=0, stop=5, step=0.1)
    
    n_data = len(x)
    n_rnd = 1000
    
    m = np.random.normal(loc=1, scale=0.3, size=n_rnd) 
    b = np.random.normal(loc=5, scale=0.3, size=n_rnd)
    
    y = m * x[:, np.newaxis] + b
    
    for val in y.transpose():
        plt.plot(x, val, alpha=0.05)
    
    # Or without the iteration:
    # plt.plot(x, y, alpha=0.05)
    
    plt.show()
    

    x[:, np.newaxis] 强制 x 成为形状为 (50, 1) 的列向量,而不是 (50,),这意味着广播有效。

    然后您可以直接迭代 numpy 数组(而不是迭代它的索引),但您必须转置数组(使用 y.transpose())否则对于每次迭代,您将获得每 1000 个随机数的 x 值.

    【讨论】:

    • 太好了,正是我想要的。谢谢。您链接的页面底部有一个死链接;感兴趣的人可以在这里找到(非常有用的)文章:EricsBroadcastingDoc。 /edit:一个后续问题,尽管@Ffisegydd:循环绘图比我做的更快,或者你为什么决定改变它?
    • 我认为你误解了我(或者我误解了你)。我明白为什么你摆脱了我的循环来生成y 本身,这看起来很像我在提出这个问题时的想法。我只是想知道为什么你为 plot 添加了一个循环,当它在没有循环的情况下工作时,就像在我的原始代码中一样,只需使用plt.plot(x, y, "k", alpha=0.05)。或者这是否在“内部”迭代索引?抱歉,我对此有点困惑。
    • 哦,是的,我明白你的意思了,这完全是代表我的大脑放屁。要么工作,我不确定哪个更快,我什至没有意识到我修改了你的原始代码。
    猜你喜欢
    • 2021-11-04
    • 1970-01-01
    • 2020-11-09
    • 1970-01-01
    • 1970-01-01
    • 2013-07-12
    • 1970-01-01
    • 2018-02-28
    • 2023-03-31
    相关资源
    最近更新 更多