我有一个来自正态分布的随机样本数组,我想就地评估每个元素的 CDF
import numpy as np
arr = np.random.normal(0, 1, 10000)
arr
array([-0.03960733, -0.58329607, -1.55133923, ..., -0.94473672,
1.24757701, -0.66197476])
我知道我可以使用 scipy.stats.norm().cdf
来做到这一点,但我仅限于使用 numpy。
我找到了这篇SO帖子,其中概述了如何使用numpy.histogram
和numpy.cumsum
做类似的事情。我如何扩展它(仅使用 numpy(以评估每个元素的 CDF,因此输出数组如下所示
from scipy import stats
stats.norm().cdf(arr)
array([0.48420309, 0.279847 , 0.06041021, ..., 0.17239665, 0.893907 ,
0.2539937 ])
这似乎可以使用两次numpy.argsort()
来实现,以获得每个随机样本的排名arr
。但是存在一些舍入误差
import numpy as np
arr = np.random.normal(0, 1, 10000)
arr
array([-0.24822623, -0.49071664, -0.75405418, ..., -0.59249804,
-0.9140224 , 0.18904534])
x = arr.argsort().argsort() # ranks of each entry in `arr`
y = np.arange(len(arr)) / len(arr)
numpy_cdfs = y[x] # sort `y` by ranks
numpy_cdfs
array([0.3973, 0.307 , 0.2204, ..., 0.2713, 0.1745, 0.5696])
如果我们与 scipy 进行比较,我们需要将绝对容差设置为 1e-2(相当高(。
from scipy import stats
scipy_cdfs = stats.norm().cdf(arr)
scipy_cdfs
array([0.40197969, 0.31181344, 0.22540834, ..., 0.27675857, 0.18035254,
0.57497136])
np.allclose(numpy_cdfs, scipy_cdfs, atol=1e-2)
True
此错误将减少我们拥有的样本越多。