Skip to content

Instantly share code, notes, and snippets.

@ThePyProgrammer
Last active August 22, 2021 17:28
Show Gist options
  • Save ThePyProgrammer/c52fc2cf9b8d1703c5270af94794feff to your computer and use it in GitHub Desktop.
Save ThePyProgrammer/c52fc2cf9b8d1703c5270af94794feff to your computer and use it in GitHub Desktop.
Computing the Pearson Correlation Coefficient in NumPy, without any involvement of SciPy.
import numpy as np
# Functions I painstakingly researched and coded with 2 shots of coffee at 3 am
def gamma(n):
"""
A Simplified Gamma Function for "powers" of 1/2
Gamma Function for Integers are given by: Γ(n) = (n-1)!
Gamma Function for Values ending with 1/2: Γ(n) = 0.5 * 1.5 * ... * (n-1) * √(π)
Gamma Function is generally given by the following expression
"""
return np.arange(1 - (n%1), n).prod() * np.pi ** (n%1)
def beta(x, y):
"""
Actual Beta Function based ont he Simplified Gamma Function above.
"""
return gamma(x)*gamma(y)/gamma(x+y)
def I(x, a, b):
if gamma(a) == np.inf or gamma(b) == np.inf or gamma(a+b) == 0: return 0
if x == 0 or x == 1: return x
if b == 1: return x ** a
if a == 1: return 1 - (1-x)**b
if b > 1: return I(x, a, b-1) + (x**a * (1-x)**(b-1))/((b-1)*beta(a, b-1))
if a > 1: return I(x, a-1, b) - (x**(a-1) * (1-x)**b)/((a-1)*beta(a-1, b))
return ((-1)**a) * I(x/(x-1), a, 1-a-b) * beta(a, 1-a-b)
def corr(data):
norm = data - data.mean(axis=0)
return norm.prod(axis=1).sum() / np.sqrt((norm**2).sum(axis=0).prod())
def p(r, bound):
return 2*I((1-abs(r))/2, bound, bound)
def pearson(data):
r = corr(data)
return r, p(r, data.shape[0]/2-1)
def pearsonr(x, y):
x, y = x - x.mean(axis=0), y - y.mean(axis=0)
r = (x.T @ y).sum(axis=0) / np.sqrt(((x**2).sum(axis=0) * (y**2).sum(axis=0)))
p_val = 2 * np.vectorize(lambda r: p(r, x.shape[0]/2-1))(r)
return np.stack((r, p_val), axis=len(r.shape))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment