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