<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
Step2:  Calculating percentiles / quantiles
Random examples from Stack Overflow
https
Step3:  I also found this post about equal frequency binning in Python useful.
statsmodels
<ASSISTANT_TASK:>
Python Code:
import numpy as np
data = np.array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
weights = np.array([1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5])
quantile = 0.25
ind_sorted = np.argsort(data)
sorted_data = data[ind_sorted]
sorted_weights = weights[ind_sorted]
Sn = np.cumsum(sorted_weights)
Pn = (Sn-0.5*sorted_weights)/Sn[-1]
np.interp(quantile, Pn, sorted_data)
np.quantile(data, 0.25)
def weighted_percentile(a, q=np.array([75, 25]), w=None):
    
    Calculates percentiles associated with a (possibly weighted) array
    Parameters
    ----------
    a : array-like
        The input array from which to calculate percents
    q : array-like
        The percentiles to calculate (0.0 - 100.0)
    w : array-like, optional
        The weights to assign to values of a.  Equal weighting if None
        is specified
    Returns
    -------
    values : np.array
        The values associated with the specified percentiles.  
    
    # Standardize and sort based on values in a
    q = np.array(q) / 100.0
    if w is None:
        w = np.ones(a.size)
    idx = np.argsort(a)
    a_sort = a[idx]
    w_sort = w[idx]
    # Get the cumulative sum of weights
    ecdf = np.cumsum(w_sort)
    # Find the percentile index positions associated with the percentiles
    p = q * (w.sum() - 1)
    # Find the bounding indices (both low and high)
    idx_low = np.searchsorted(ecdf, p, side='right')
    idx_high = np.searchsorted(ecdf, p + 1, side='right')
    idx_high[idx_high > ecdf.size - 1] = ecdf.size - 1
    # Calculate the weights 
    weights_high = p - np.floor(p)
    weights_low = 1.0 - weights_high
    # Extract the low/high indexes and multiply by the corresponding weights
    x1 = np.take(a_sort, idx_low) * weights_low
    x2 = np.take(a_sort, idx_high) * weights_high
    # Return the average
    return np.add(x1, x2)
weighted_percentile(data, q=np.array([10, 25, 50, 75, 90, 100]), w=weights)
def weighted_percentile2(data, weights, perc):
    
    perc : percentile in [0-1]!
    
    ix = np.argsort(data)
    data = data[ix] # sort data
    weights = weights[ix] # sort weights
    cdf = (np.cumsum(weights) - 0.5 * weights) / np.sum(weights) # 'like' a CDF function
    return np.interp(perc, cdf, data)
weighted_percentile2(data, weights, 0.1)
Explanation: Calculating percentiles / quantiles
Random examples from Stack Overflow
https://stackoverflow.com/questions/21844024/weighted-percentile-using-numpy
End of explanation
from statsmodels.stats.weightstats import DescrStatsW
wq = DescrStatsW(data=np.arange(0, 101), weights=np.ones(101)* 1.5)
wq.quantile(probs=np.arange(0, 1.01, 0.01), return_pandas=False)
Explanation: I also found this post about equal frequency binning in Python useful.
statsmodels
End of explanation
<END_TASK>