考虑直线y = m * x + b
的非常基本的蒙特卡罗模拟,例如:在参数m
和b
中可视化不确定性的影响。 m
和b
均来自正态分布。来自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中是否有类似的东西,或者甚至包含类似这些东西的包?
答案 0 :(得分:7)
您可以使用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值。