【问题标题】:Vectorizing a comparison in numpy在 numpy 中向量化比较
【发布时间】:2014-02-17 13:21:23
【问题描述】:

如何在 NumPy 中对这个循环进行矢量化?它使用来自 NumPy 的 binomial() 函数的采样来估计在 55 个事件中恰好发生特定类型的 m 的概率,其中 m 发生的概率为 5%;即它估计55Cm.(0.05)^m.(0.95)^(55-m)。其中 55Cm = 55!/(m!.(55-m)!)

import numpy as np
M = 7
m = np.arange(M+1)
ntrials = 1000000
p = np.empty(M+1)
for r in m:
    p[r] = np.sum(np.random.binomial(55, 0.05, ntrials)==r)/ntrials

【问题讨论】:

  • 如果你能用数学术语写一个关于你的代码实际在做什么的简短描述,那就太好了。
  • 不能用纯分析法解决这个问题,而不是用数值方法吗?
  • 是的,当然 - 例如,请参阅问题中的公式。这是从分布中随机抽样的演示。
  • 矢量化可能不会让你买太多;计算 1M 随机数的时间将使循环开销相形见绌。

标签: numpy comparison broadcast


【解决方案1】:

这是等效的代码:

p = np.zeros(M+1)
print p

我想你不打算让你的输出总是全为零,但它是!所以要做的第一件事是在你的np.sum() 调用中添加一个dtype=float 参数。有了这个,我们可以像这样对整个事物进行矢量化:

samples = np.random.binomial(55, 0.05, (ntrials, M+1))
p = np.sum(samples == m, dtype=float, axis=0) / ntrials

这会产生等效但不完全相同的结果。原因是随机数生成是以不同的顺序完成的,因此您将得到一个“正确”但与旧代码不同的答案。如果您想要与之前相同的结果,您可以通过将第一行更改为:

samples = p.random.binomial(55, 0.05, (M+1, ntrials)).T

然后您按照与之前相同的顺序进行绘制,而没有实际的性能损失。

【讨论】:

  • 谢谢 - 我在 Python 3 上(尽管我的 print 语句可能给人的印象),所以 dtype 不是问题。有没有办法在不存储samples这样的大数组的情况下做到这一点?
  • 我不知道。您在这里要解决的真正问题是什么? CPU时间太慢?内存太大?在某些时候,您最好编写一些 C 或 C++ 代码并调用它。
  • 这只是一个演示,但我希望尽可能高效:当前的解决方案对每个概率采样ntrials 次,并在只需要计算它们时存储这些值。跨度>
猜你喜欢
  • 1970-01-01
  • 2014-02-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多