微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

numpy的快速蒙特卡洛仿真?

我正在遵循R和Python中“进行贝叶斯数据分析”中的练习.

我想找到一种使用恒定空间的快速蒙特卡洛模拟方法.

下面的问题很简单,但是可以很好地测试不同的方法

ex 4.3

Determine the exact probability of drawing a 10 from a shuffled pinochle deck. (In a pinochle deck, there are 48 cards. There are six values: 9, 10, Jack, Queen, King, Ace. There are two copies of each value in each of the standard four suits: hearts, diamonds, clubs, spades.)

(A) What is the probability of getting a 10?

当然,答案是1/6.

我能找到的最快解决方案(与R的速度相当)是使用np.random.choice生成大量的纸牌抽奖,然后应用计数器.我不喜欢不必要地创建数组的想法,因此我尝试使用字典和for循环,一次绘制一张卡,并增加该卡类型的数量.令我惊讶的是,它慢得多!

下面是我测试的3种方法的完整代码. _有没有一种方法可以像method1()一样执行,但是使用恒定空间呢?

Python代码:(Google Colab link)

deck = [c for c in ['9','10','Jack','Queen','King','Ace'] for _ in range(8)]
num_draws = 1000000

def method1():
  draws = np.random.choice(deck, size=num_draws, replace=True)
  df = pd.DataFrame([Counter(draws)])/num_draws
  print(df)

def method2():
  card_counts = defaultdict(int)
  for _ in range(num_draws):
    card_counts[np.random.choice(deck, replace=True)] += 1
  df = pd.DataFrame([card_counts])/num_draws
  print(df)

def method3():
  card_counts = defaultdict(int)
  for _ in range(num_draws):
    card_counts[deck[random.randint(0, len(deck)-1)]] += 1
  df = pd.DataFrame([card_counts])/num_draws
  print(df)

Python timeit()结果:

方法1:1.2997

方法2:23.0626

方法3:5.5859

R代码

card = sample(deck, numDraws, replace=TRUE)
print(as.data.frame(table(card)/numDraws))

解决方法:

这是np.unique np.bincount

def unique():    
    unq,ids = np.unique(deck, return_inverse=True)
    all_ids = np.random.choice(ids, size=num_draws, replace=True)
    ar = np.bincount(all_ids)/num_draws
    return pd.DataFrame(ar[None], columns=unq)

NumPy在这里有何帮助?

有两项重大改进正在帮助我们:

>我们将字符串数据转换为数字. NumPy可以很好地处理此类数据.为此,我们使用np.unique.
>我们使用np.bincount代替计数步骤.再次,它很好地适用于数字数据,并且在此方法开始时我们已经从数字转换中获得了它.
>通常,NumPy可以很好地处理大数据.

给定样本数据集的时间与最快的方法进行比较1-

In [177]: %timeit method1()
328 ms ± 16.3 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

In [178]: %timeit unique()
12.4 ms ± 265 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐