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)

相关文章

转载:一文讲述Pandas库的数据读取、数据获取、数据拼接、数...
Pandas是一个开源的第三方Python库,从Numpy和Matplotlib的基...
整体流程登录天池在线编程环境导入pandas和xrld操作EXCEL文件...
 一、numpy小结             二、pandas2.1为...
1、时间偏移DateOffset对象DateOffset类似于时间差Timedelta...
1、pandas内置样式空值高亮highlight_null最大最小值高亮背景...