From thinkstats2 the O'Reilly text.
class cdf(object):
def ValueArray(self, ps):
"""Returns InverseCDF(p), the value that corresponds to probability p.
Args:
ps: NumPy array of numbers in the range [0, 1]
Returns:
NumPy array of values
"""
ps = np.asarray(ps)
if np.any(ps < 0) or np.any(ps > 1):
raise ValueError('Probability p must be in range [0, 1]')
index = np.searchsorted(self.ps, ps, side='left')
return self.xs[index]
def Sample(self, n):
"""Generates a random sample from this distribution.
n: int length of the sample
returns: NumPy array
"""
ps = np.random.random(n) # chooses n random terms in [0,1)
return self.ValueArray(ps)
# so here i choose an
# ps are defined as the % of getting <= a given term in the cdf
# ValueArray returns the val associated with a % <= desired
def ResampleRowsWeighted(df, column='finalwgt'):
weights = df[column] # giving us the desired weights
cdf = Cdf(dict(weights)) # creating a cdf object
indices = cdf.Sample(len(weights)) # returns list of vals
sample = df.loc[indices] # returns chosen rows
return sample
why do we use a cdf instead of pdf?
with a cdf were most likely to land in the biggest gap, the largest difference between 2 percentiles
with a pmf we can use a series and add each perc together, and then pick a random number in [0,1) where larger weights are more likely to get picked