是否有更有效的方法来枚举 python 或 R 中离散随机变量的每个可能结果的概率?
is there an more efficient way to enumerate probability for each of possible outcome of a discrete random variable in python or R?
我在理论上计算 Python 中的 pmf。这是代码。
>>> a_coin = np.array([0,1])
>>> three_coins = np.array(np.meshgrid(a_coin,a_coin,a_coin)).T.reshape(-1,3)
>>> heads = np.sum(three_coins, axis = 1)
>>> df = pd.DataFrame({'heads': heads, 'prob': 1/8})
>>> np.array(df.groupby('heads').sum()['prob'])
array([0.125, 0.375, 0.375, 0.125])
这段代码模拟了 3 个公平硬币的 1 次抛掷。
可能的结果是 {0,1,2,3}。
最后一行代码分别计算每种可能结果的概率。
我必须在 np.meshgrid(a_coin,...,a_coin) 中输入 10 'a_coin' 如果我想计算抛出 10 个公平硬币的 pmf ,这似乎很无聊且效率低下。
问题是,在 python 或 R 中是否有更有效的方法?
以下是在 R 中的操作方法:
> sapply(0:3, choose, n=3)/sum(sapply(0:3, choose, n=3))
[1] 0.125 0.375 0.375 0.125
choose
函数为您提供二项式系数。要将它们转化为概率,只需除以它们的总和:
sapply(0:10, choose, n=10)
[1] 1 10 45 120 210 252 210 120 45 10 1
sapply(0:10, choose, n=10)/ sum( sapply(0:10, choose, n=10))
[1] 0.0009765625 0.0097656250 0.0439453125 0.1171875000 0.2050781250 0.2460937500 0.2050781250
[8] 0.1171875000 0.0439453125 0.0097656250 0.0009765625
看来你不是真的要枚举,而是要计算。如果您需要枚举 10 次连续 "fair" 二项式抽取的结果,那么您可以使用 combn
11 次。
使用Python标准库,您可以获得有理数形式的概率(这是精确解),例如
from fractions import Fraction
from math import factorial
n=30
[Fraction(factorial(n), factorial(n - j)) * Fraction(1, factorial(j) * 2 ** n) for j in range(0, n + 1)]
这可以很容易地转换为浮点数,例如
list(map(float, [Fraction(factorial(n), factorial(n - j)) * Fraction(1, factorial(j) * 2 ** n) for j in range(0, n + 1)]))
这是一个基于 fft
的 numpy
解决方案:
import numpy as np
from scipy import fftpack
def toss(n=10, p=0.5):
t1 = np.zeros(fftpack.next_fast_len(n+1))
t1[:2] = 1-p, p
f1 = fftpack.rfft(t1)
c1 = f1[1:(len(t1) - 1) // 2 * 2 + 1].view(f'c{2*t1.itemsize}')
c1 **= n
f1[::(len(t1) + 1) // 2 * 2 - 1] **= n
return fftpack.irfft(f1)[:n+1]
例如:
>>> toss(3)
array([0.125, 0.375, 0.375, 0.125])
>>> toss(10)
array([0.00097656, 0.00976562, 0.04394531, 0.1171875 , 0.20507813,
0.24609375, 0.20507813, 0.1171875 , 0.04394531, 0.00976562,
0.00097656])
我在理论上计算 Python 中的 pmf。这是代码。
>>> a_coin = np.array([0,1])
>>> three_coins = np.array(np.meshgrid(a_coin,a_coin,a_coin)).T.reshape(-1,3)
>>> heads = np.sum(three_coins, axis = 1)
>>> df = pd.DataFrame({'heads': heads, 'prob': 1/8})
>>> np.array(df.groupby('heads').sum()['prob'])
array([0.125, 0.375, 0.375, 0.125])
这段代码模拟了 3 个公平硬币的 1 次抛掷。 可能的结果是 {0,1,2,3}。 最后一行代码分别计算每种可能结果的概率。
我必须在 np.meshgrid(a_coin,...,a_coin) 中输入 10 'a_coin' 如果我想计算抛出 10 个公平硬币的 pmf ,这似乎很无聊且效率低下。
问题是,在 python 或 R 中是否有更有效的方法?
以下是在 R 中的操作方法:
> sapply(0:3, choose, n=3)/sum(sapply(0:3, choose, n=3))
[1] 0.125 0.375 0.375 0.125
choose
函数为您提供二项式系数。要将它们转化为概率,只需除以它们的总和:
sapply(0:10, choose, n=10)
[1] 1 10 45 120 210 252 210 120 45 10 1
sapply(0:10, choose, n=10)/ sum( sapply(0:10, choose, n=10))
[1] 0.0009765625 0.0097656250 0.0439453125 0.1171875000 0.2050781250 0.2460937500 0.2050781250
[8] 0.1171875000 0.0439453125 0.0097656250 0.0009765625
看来你不是真的要枚举,而是要计算。如果您需要枚举 10 次连续 "fair" 二项式抽取的结果,那么您可以使用 combn
11 次。
使用Python标准库,您可以获得有理数形式的概率(这是精确解),例如
from fractions import Fraction
from math import factorial
n=30
[Fraction(factorial(n), factorial(n - j)) * Fraction(1, factorial(j) * 2 ** n) for j in range(0, n + 1)]
这可以很容易地转换为浮点数,例如
list(map(float, [Fraction(factorial(n), factorial(n - j)) * Fraction(1, factorial(j) * 2 ** n) for j in range(0, n + 1)]))
这是一个基于 fft
的 numpy
解决方案:
import numpy as np
from scipy import fftpack
def toss(n=10, p=0.5):
t1 = np.zeros(fftpack.next_fast_len(n+1))
t1[:2] = 1-p, p
f1 = fftpack.rfft(t1)
c1 = f1[1:(len(t1) - 1) // 2 * 2 + 1].view(f'c{2*t1.itemsize}')
c1 **= n
f1[::(len(t1) + 1) // 2 * 2 - 1] **= n
return fftpack.irfft(f1)[:n+1]
例如:
>>> toss(3)
array([0.125, 0.375, 0.375, 0.125])
>>> toss(10)
array([0.00097656, 0.00976562, 0.04394531, 0.1171875 , 0.20507813,
0.24609375, 0.20507813, 0.1171875 , 0.04394531, 0.00976562,
0.00097656])