def gini(values, weights = None, bin_size = None):
    """
    Gini coefficient (normalized to 1)
    Using fastgini formula :


                      i=N      j=i
                      SUM W_i*(SUM W_j*X_j - W_i*X_i/2)
                      i=1      j=1
          G = 1 - 2* ----------------------------------
                           i=N             i=N
                           SUM W_i*X_i  *  SUM W_i
                           i=1             i=1


        where observations are sorted in ascending order of X.

    From http://fmwww.bc.edu/RePec/bocode/f/fastgini.html
    """
    if weights is None:
        weights = ones(len(values))

    df = pd.DataFrame({'x': values, 'w': weights})
    df = df.sort_values(by='x')
    x = df['x']
    w = df['w']
    wx = w * x

    cdf = cumsum(wx) - 0.5 * wx
    numerator = (w * cdf).sum()
    denominator = ((wx).sum()) * (w.sum())
    gini = 1 - 2 * (numerator / denominator)

    return gini
Gini coefficient (normalized to 1)
    Using fastgini formula :


                      i=N      j=i
                      SUM W_i*(SUM W_j*X_j - W_i*X_i/2)
                      i=1      j=1
          G = 1 - 2* ----------------------------------
                           i=N             i=N
                           SUM W_i*X_i  *  SUM W_i
                           i=1             i=1


        where observations are sorted in ascending order of X.

    From http://fmwww.bc.edu/RePec/bocode/f/fastgini.html