(total, data, accounting_column, prob_column=None, max_iterations=50)
return closest, matched
Sample rows with accounting with replacement.

    Parameters
    ----------
    total : int
        The control total the sampled rows will attempt to match.
    data: pandas.DataFrame
        Table to sample from.
    accounting_column: string
        Name of column with accounting totals/quantities to apply towards the control.
    prob_column: string, optional, default None
        Name of the column in the data to provide probabilities or weights.
    max_iterations: int, optional, default 50
        When using an accounting attribute, the maximum number of sampling iterations
        that will be applied.

    Returns
    -------
    sample_rows : pandas.DataFrame
        Table containing the sample.
    matched: bool
        Indicates if the total was matched exactly.
Sample rows with accounting with replacement.
Sample rows with accounting with replacement .
def accounting_sample_replace(total, data, accounting_column, prob_column=None, max_iterations=50):
    """
    Sample rows with accounting with replacement.

    Parameters
    ----------
    total : int
        The control total the sampled rows will attempt to match.
    data: pandas.DataFrame
        Table to sample from.
    accounting_column: string
        Name of column with accounting totals/quantities to apply towards the control.
    prob_column: string, optional, default None
        Name of the column in the data to provide probabilities or weights.
    max_iterations: int, optional, default 50
        When using an accounting attribute, the maximum number of sampling iterations
        that will be applied.

    Returns
    -------
    sample_rows : pandas.DataFrame
        Table containing the sample.
    matched: bool
        Indicates if the total was matched exactly.

    """
    # check for probabilities
    p = get_probs(data, prob_column)

    # determine avg number of accounting items per sample (e.g. persons per household)
    per_sample = data[accounting_column].sum() / (1.0 * len(data.index.values))

    curr_total = 0
    remaining = total
    sample_rows = pd.DataFrame()
    closest = None
    closest_remain = total
    matched = False

    for i in range(0, max_iterations):

        # stop if we've hit the control
        if remaining == 0:
            matched = True
            break

        # if sampling with probabilities, re-caclc the # of items per sample
        # after the initial sample, this way the sample size reflects the probabilities
        if p is not None and i == 1:
            per_sample = sample_rows[accounting_column].sum() / (1.0 * len(sample_rows))

        # update the sample
        num_samples = int(math.ceil(math.fabs(remaining) / per_sample))

        if remaining > 0:
            # we're short, add to the sample
            curr_ids = np.random.choice(data.index.values, num_samples, p=p)
            sample_rows = pd.concat([sample_rows, data.loc[curr_ids]])
        else:
            # we've overshot, remove from existing samples (FIFO)
            sample_rows = sample_rows.iloc[num_samples:].copy()

        # update the total and check for the closest result
        curr_total = sample_rows[accounting_column].sum()
        remaining = total - curr_total

        if abs(remaining) < closest_remain:
            closest_remain = abs(remaining)
            closest = sample_rows

    return closest, matched
def accounting_sample_replace ( total , data , accounting_column , prob_column = None , max_iterations = 50 ) : # check for probabilities p = get_probs ( data , prob_column ) # determine avg number of accounting items per sample (e.g. persons per household) per_sample = data [ accounting_column ] . sum ( ) / ( 1.0 * len ( data . index . values ) ) curr_total = 0 remaining = total sample_rows = pd . DataFrame ( ) closest = None closest_remain = total matched = False for i in range ( 0 , max_iterations ) : # stop if we've hit the control if remaining == 0 : matched = True break # if sampling with probabilities, re-caclc the # of items per sample # after the initial sample, this way the sample size reflects the probabilities if p is not None and i == 1 : per_sample = sample_rows [ accounting_column ] . sum ( ) / ( 1.0 * len ( sample_rows ) ) # update the sample num_samples = int ( math . ceil ( math . fabs ( remaining ) / per_sample ) ) if remaining > 0 : # we're short, add to the sample curr_ids = np . random . choice ( data . index . values , num_samples , p = p ) sample_rows = pd . concat ( [ sample_rows , data . loc [ curr_ids ] ] ) else : # we've overshot, remove from existing samples (FIFO) sample_rows = sample_rows . iloc [ num_samples : ] . copy ( ) # update the total and check for the closest result curr_total = sample_rows [ accounting_column ] . sum ( ) remaining = total - curr_total if abs ( remaining ) < closest_remain : closest_remain = abs ( remaining ) closest = sample_rows return closest , matched