4

I'm looking to generate a binomial-esque distribution. I want a binomial distribution but I want it centred around zero (I know this doesn't make much sense with respect to the definition of binomial distributions but still, this is my goal.)

The only way I have found of doing this in python is:

def zeroed_binomial(n,p,size=None): return numpy.random.binomial(n,p,size) - n*p 

Is there a real name for this distribution? Does this code actually give me what I want (and how can I tell)? Is there a cleaner / nicer / canonical / already implemented way of doing this?

6
  • 1
    i would only see sense in such a distribution if p = 0.5 (otherwise, the notion of centered seems far-fetched) Commented Mar 22, 2013 at 14:28
  • Perhaps centred is the wrong word, I mean that the most frequent element should be zero. Commented Mar 22, 2013 at 14:29
  • so basically a binomial such as f(0) = max(f(x)). What are you doing with that ? Commented Mar 22, 2013 at 14:32
  • Testing out a theory I have for my steganography paper :P. Commented Mar 22, 2013 at 14:36
  • 1
    n*p is the mean of the binomial distribution. The most frequent element is the mode, and according to wikipedia it is either floor((n + 1)p) or floor((n + 1)p) − 1 Commented Mar 22, 2013 at 15:52

2 Answers 2

3

What you're doing is fine if you want a "discretized" normal distribution centered around 0. If you want integer values, you should round n*p before subtracting.

But the limit of the binomial distribution is just the normal distribution when n becomes large and with p bounded away from 0 or 1. since n*p is not going to be an integer except for certain values, why not just use the normal distribution?

Sign up to request clarification or add additional context in comments.

4 Comments

This the all true for large N, but the op might want a binomial with a small N, in which case the normal distribution would not be a good approximation.
Good call on the rounding of n*p.
@AndrewMao Could you elaborate a bit on what you mean by rounding $n*p$ before subtracting in order to get "discretized" normal distribution?
@Alex if you want an integer-valued support ..., -2, -1, 0, 1, 2, ... instead of real-valued ones that are oddly shifted like ..., -1.714, -0.714, 0.286, 1.286, .... Of course, the mean of this adjusted distribution will not be 0.
3

The probability distributions implemented in the scipy.stats module allow you to shift distributions arbitrarily by specifying the loc keyword in the constructor. To get a binomial distribution with mean shifted close to 0, you can call

p = stats.binom(N, p, loc=-round(N*p)) 

(Be sure to use an integer value for loc with a discrete distribution.)

Here's an example:

p = stats.binom(20, 0.1, loc=-2) x = numpy.arange(-3,5) bar(x, p.pmf(x)) 

bar plot

Edit:

To generate the actual random numbers, use the rvs() method which comes with every random distribution in the scipy.stats module. For example:

>>> stats.binom(20,0.1,loc=-2).rvs(10) array([-2, 0, 0, 1, 1, 1, -1, 1, 2, 0]) 

2 Comments

I'm actually looking for a list of random numbers that conform to a distribution, not just what the distribution looks like. I suppose I could generate the numbers from the distribution but that doesn't feel clean.
@jhoyla Every distribution in scipy.stats of course comes with a method to generate the random numbers. See my edit. Why do you think it doesn't feel clean?

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.