Как получить баллы CDF на месте, используя numpy? - PullRequest
1 голос
/ 16 апреля 2019

У меня есть массив случайных выборок из нормального распределения, где я хочу оценить 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 ])

1 Ответ

1 голос
/ 16 апреля 2019

Похоже, этого можно достичь, дважды набрав 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

Эта ошибка уменьшит количество сэмплов, которые у нас есть.

...