Instantly share code, notes, and snippets.

Embed
What would you like to do?
pl/python circular quartiles function
create type numeric_quartiles_plus as (
min float,
q05 float,
q10 float,
q25 float,
q50 float,
q75 float,
q90 float,
q95 float,
max float,
stddev float,
mean float
);
create or replace function circular_quartiles_py (
valarray float[], circ_size float default 360 )
returns numeric_quartiles_plus
language plpythonu
as $f$
from scipy.stats.mstats import mquantiles
from numpy import append, arange, array, diff, sort, all, repeat, mean, std
#remove nulls from the incoming array
samples = array([p for p in valarray if p is not None])
n = len(samples)
# check for the empty set
if n == 0:
return (None,) * 11
# sort the raw data
x = sort(samples % (circ_size))
# find the single largest gap
spacings = append(diff(x), x[0] - x[n-1] + circ_size)
max_spacing = arange(n)[spacings == max(spacings)] + 1
# take the first largest spacing and assume its the gap
if max_spacing[0] == n:
offset = 0
else:
offset = circ_size - x[max_spacing[0]]
# adjust all values by the gap location
xoffset = sort((x + offset) % (circ_size))
# calculate percentiles
quant = mquantiles(xoffset,
prob=[0, 0.05, 0.1, 0.25, 0.5, 0.75, 0.9, 0.95, 1],
alphap=1,
betap=1) - offset
# add mean and stddev
quant2 = append(append(quant, std(xoffset) - offset), mean(xoffset) - offset)
rez = [val + circ_size if val < 0 else val for val in quant2]
return tuple(rez)
$f$;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment