Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how can I check whether a scipy distribution is discrete?

I would like to check whether a scipy distribution is discrete or continuous. The test should work whether the object is a frozen distribution object from a named distribution, or an instance of a custom rv_discrete or rv_continuous distribution.

My first thought was to check the type of the variable, but this does not seem to correspond neatly to continuous vs. discrete. For example, here are four distributions:

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))

And here are their types:

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

For now I have implemented an is_discrete() function by trying to access the pmf() method (which only discrete distributions have) but I'm not sure if this is the cleanest or most reliable method. Is there a better way?

def is_discrete(dist):
    try:
        _ = dist.pmf(0)
        return True
    except:
        return False
like image 657
LarrySnyder610 Avatar asked Oct 20 '25 04:10

LarrySnyder610


1 Answers

You can use isinstance built-in function to define custom checks:

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)

Which will result in:

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

like image 196
FBruzzesi Avatar answered Oct 22 '25 18:10

FBruzzesi



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!