Как я могу проверить, является ли распределение Scipy дискретным? - PullRequest
2 голосов
/ 30 апреля 2020

Я хотел бы проверить, является ли распределение scipy дискретным или непрерывным. Тест должен работать независимо от того, является ли объект замороженным распределением из именованного распределения или экземпляром пользовательского rv_discrete или rv_continuous распределения.

Моей первой мыслью было проверить тип переменной, но это, кажется, не соответствует аккуратно непрерывному против дискретного. Например, вот четыре дистрибутива:

from scipy.stats import *
import numpy as np

dist_norm = norm(10, 2)
dist_poisson = poisson(10)

class continuous_gen(rv_continuous):
    def _pdf(self, x, *args):
        if x >= 0 and x <= 1:
            return 1
        else:
            return 0
dist_contin = continuous_gen()

xk = np.arange(7)
pk = (0.1, 0.2, 0.3, 0.1, 0.1, 0.0, 0.2)
dist_discrete = rv_discrete(values=(xk, pk))

А вот их типы:

type(dist_norm)
Out[59]: scipy.stats._distn_infrastructure.rv_frozen
type(dist_poisson)
Out[60]: scipy.stats._distn_infrastructure.rv_frozen
type(dist_contin)
Out[61]: __main__.continuous_gen
type(dist_discrete)
Out[62]: scipy.stats._distn_infrastructure.rv_sample

На данный момент я реализовал функцию is_discrete(), пытаясь получить доступ к pmf() метод (который есть только в дискретных дистрибутивах), но я не уверен, что это самый чистый или самый надежный метод Есть ли лучший способ?

def is_discrete(dist):
    try:
        _ = dist.pmf(0)
        return True
    except:
        return False

1 Ответ

2 голосов
/ 30 апреля 2020

Вы можете использовать встроенную функцию isinstance для определения пользовательских проверок:

from scipy.stats import poisson, norm, rv_discrete, rv_continuous

def is_discrete(dist):

    if hasattr(dist, 'dist'):
        return isinstance(dist.dist, rv_discrete)
    else: return isinstance(dist, rv_discrete)

def is_continuous(dist):

    if hasattr(dist, 'dist'):
        return isinstance(dist.dist, rv_continuous)
    else: return isinstance(dist, rv_continuous)

, что приведет к:

class continuous_gen(rv_continuous):
    def _pdf(self, x, *args):
        if x >= 0 and x <= 1:
            return 1
        else:
            return 0
dist_contin = continuous_gen()
dist_poisson = poisson(10)

is_discrete(dist_contin)
#False
is_continuous(dist_contin)
#True
is_discrete(dist_poisson)
#True
is_continuous(dist_poisson)
#False

...