Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Calculate the Cumulative Distribution Function (CDF) in Python

How can I calculate in python the Cumulative Distribution Function (CDF)?

I want to calculate it from an array of points I have (discrete distribution), not with the continuous distributions that, for example, scipy has.

like image 491
wizbcn Avatar asked Jul 16 '14 18:07

wizbcn


People also ask

How do you calculate CDF in Python?

The easiest way to calculate normal CDF probabilities in Python is to use the norm. cdf() function from the SciPy library. What is this? The probability that a random variables takes on a value less than 1.96 in a standard normal distribution is roughly 0.975.

How do you find CDF from data?

Popular Answers (1) Given a random variable X, its cdf is the function F(x) = Prob(X <= x) where the variable x runs through the real numbers. The distribution is called continuous if F(x) is the integral from -infinity to x of a function f called the density function.

How CDF is calculated?

The cumulative distribution function (CDF) of random variable X is defined as FX(x) = P(X ≤ x), for all x ∈ R. Note that the subscript X indicates that this is the CDF of the random variable X.


2 Answers

(It is possible that my interpretation of the question is wrong. If the question is how to get from a discrete PDF into a discrete CDF, then np.cumsum divided by a suitable constant will do if the samples are equispaced. If the array is not equispaced, then np.cumsum of the array multiplied by the distances between the points will do.)

If you have a discrete array of samples, and you would like to know the CDF of the sample, then you can just sort the array. If you look at the sorted result, you'll realize that the smallest value represents 0% , and largest value represents 100 %. If you want to know the value at 50 % of the distribution, just look at the array element which is in the middle of the sorted array.

Let us have a closer look at this with a simple example:

import matplotlib.pyplot as plt import numpy as np  # create some randomly ddistributed data: data = np.random.randn(10000)  # sort the data: data_sorted = np.sort(data)  # calculate the proportional values of samples p = 1. * np.arange(len(data)) / (len(data) - 1)  # plot the sorted data: fig = plt.figure() ax1 = fig.add_subplot(121) ax1.plot(p, data_sorted) ax1.set_xlabel('$p$') ax1.set_ylabel('$x$')  ax2 = fig.add_subplot(122) ax2.plot(data_sorted, p) ax2.set_xlabel('$x$') ax2.set_ylabel('$p$') 

This gives the following plot where the right-hand-side plot is the traditional cumulative distribution function. It should reflect the CDF of the process behind the points, but naturally, it is not as long as the number of points is finite.

cumulative distribution function

This function is easy to invert, and it depends on your application which form you need.

like image 62
DrV Avatar answered Sep 24 '22 14:09

DrV


Assuming you know how your data is distributed (i.e. you know the pdf of your data), then scipy does support discrete data when calculating cdf's

import numpy as np import scipy import matplotlib.pyplot as plt import seaborn as sns  x = np.random.randn(10000) # generate samples from normal distribution (discrete data) norm_cdf = scipy.stats.norm.cdf(x) # calculate the cdf - also discrete  # plot the cdf sns.lineplot(x=x, y=norm_cdf) plt.show() 

enter image description here

We can even print the first few values of the cdf to show they are discrete

print(norm_cdf[:10]) >>> array([0.39216484, 0.09554546, 0.71268696, 0.5007396 , 0.76484329,        0.37920836, 0.86010018, 0.9191937 , 0.46374527, 0.4576634 ]) 

The same method to calculate the cdf also works for multiple dimensions: we use 2d data below to illustrate

mu = np.zeros(2) # mean vector cov = np.array([[1,0.6],[0.6,1]]) # covariance matrix # generate 2d normally distributed samples using 0 mean and the covariance matrix above x = np.random.multivariate_normal(mean=mu, cov=cov, size=1000) # 1000 samples norm_cdf = scipy.stats.norm.cdf(x) print(norm_cdf.shape) >>> (1000, 2) 

In the above examples, I had prior knowledge that my data was normally distributed, which is why I used scipy.stats.norm() - there are multiple distributions scipy supports. But again, you need to know how your data is distributed beforehand to use such functions. If you don't know how your data is distributed and you just use any distribution to calculate the cdf, you most likely will get incorrect results.

like image 37
PyRsquared Avatar answered Sep 23 '22 14:09

PyRsquared