Я выбрал серию непрерывных распределений SciPy для моделирования Монте-Карло и собираюсь взять большое количество выборок из этих распределений. Однако я хотел бы иметь возможность брать коррелированные выборки, так что i
-ая выборка берет, например, 90-й процентиль от каждого из распределений.
При этом я обнаружил причуду в производительности SciPy:
# very fast way to many uncorrelated samples of length n
for shape, loc, scale, in distro_props:
sp.stats.norm.rvs(*shape, loc=loc, scale=scale, size=n)
# verrrrryyyyy slow way to take correlated samples of length n
correlate = np.random.uniform(size=n)
for shape, loc, scale, in distro_props:
sp.stats.norm.ppf(correlate, *shape, loc=loc, scale=scale)
Большинство результатов об этом утверждают, что медлительность в этих дистрибутивах SciPy из проверки типа и т. Д. c. оберток. Однако когда я профилировал код, большая часть времени была потрачена на основную математическую функцию [_continuous_distns.py:179(_norm_pdf)]
1 . Кроме того, он масштабируется с n
, подразумевая, что он циклически проходит через каждый элемент.
Документы SciPy на rv_continuous почти предполагают, что подкласс должен переопределить это для производительности, но это кажется странным, что я бы запрятал в SciPy, чтобы ускорить их PPF. Я бы просто вычислил это для нормалей по формуле ppf, но я также использую lognormal и skewed normal, которые более трудны для реализации.
Итак, что является лучшим способом в Python для вычисления быстрый ppf для нормального, логнормального и искаженного нормального распределения? Или, в более широком смысле, взять коррелированные выборки из нескольких таких распределений?