How do I bootstrap a Dataset/DataFrame with multiple continuous and categorical columns?

For eg: Say I'm trying to bootstrap the colour distribution of M&M's and I have 50 bags (samples) each with recorded counts of 6 colours, but the samples/bags randomly come from two factories, and have 2 different time stamps on the sample/bag packets.

What would be a good method of bootstrapping this kind of dataset? Using loops that resample slices by categorical values? eg: Split the dataset into serial_no groups E2 and E1, resample those with replacement and combine, then do the same for serial_time etc...

Or can the whole dataset be resampled at once? If there happens to be subtle patterns within 'E2' data for eg, how is that preserved in bootstrapping?

Original Dataset

# create dataframes for serial_no columns.
E1_bs = pd.DataFrame()
E2_bs = pd.DataFrame()

# proportinal sample with replacement
E1_df = df[df['serial_no'] == 'E2']
sample_size = len(E1_df)*10
for i in range(len(E1_df)):
    E1_swr = pd.DataFrame(E2_df.sample(sample_size, replace=True))
    E1_bs = pd.concat([E1_bs,E1_swr],axis=0)
E2_df = df[df[['serial_no'] == 'E1']
sample_size = len(E2_df)*10
for i in range(len(E2_df)):
    E2_swr = pd.DataFrame(E2_df.sample(sample_size, replace=True))
    E2_bs = pd.concat([E2_bs,E2_swr],axis=0)

bootstrap = pd.concat([E2_bs,E1_bs],axis=0)

If I do this for all of the categorical columns (serial_no and serial_time in this case) and add them together as one dataset, I get different means (significantly) compared to if I just sample the whole thing at once using the same total amount of samples).

# Compared to bootstrapping the whole thing
sample_with_replacement = pd.DataFrame(df.sample(len(bootstrap), replace=True))

Here you have an example on how to carry out a bootstrap selection from any given set of data, based on (as you suggested) using loops and randomly selecting indexes to recreate a simulated new bag from the whole population of M&Ms. The criteria should be pretty the same for different kind of data, since what you actually do is simulate the selection of samples from a population.

It could be something like:

-bags you have from different factories:

bag_1 = ['blue']*15 + ['red']*15 + ['green']*10 + ['orange']10
bag_2 = ['blue']*14 + ['red']*16 + ['green']*9 + ['orange']*11
bag_3 = ['blue']*16 + ['red']*15 + ['green']*11 + ['orange']*8

-color distributions per bag:

import seaborn as sns
import pandas as pd

bags_df = pd.DataFrame({'bag': [1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3], 
                     'color': ['blue','red', 'green', 'orange', 'blue','red', 
                     'green', 'orange', 'blue','red', 'green', 'orange'], 
                     'count': [15, 15, 10, 10, 14, 16, 9, 11, 16, 15, 11, 8]})

ax = sns.barplot(x="bag", y="count", hue="color", data=bags_df)

enter image description here

-now your population would be all the bags together inb a big bag:

super_bag = bag_1+bag_2+bag_3

-and here is where you do the actual bootstrap:

from numpy.random import seed, rand, randint, randn

# seed random number generator

bootstrap_bags_dict = {}
for i in range(10):
    bootstrap_bags_dict['sub_bag_'+str(i)] = []
    # bootstrap sample
    boots_indices = randint(0, 50, 25)
    for idx in boots_indices:

and you get a dictionary with 10 bags like:

enter image description here

In case you want to see if there is any difference in, for instace, the red color distribution coming from factory 1 or 2, I would:

  • split the dataset by factory1 and factory2, get the red M&Ms count for each one
  • then shuffle all the M&Ms in a big bag as coming from the same factory; here, your initial hypothesis is that there is no difference in receiving red M&Ms from both factories
  • as explained here , you can compare by permutation and hypothesis testing if the difference between bootstrapped samples from your big bag (as considering both bags from the same factory) is statistically different compared to the difference between the 2 initial factories bags (it might sound hard to know, some code about it can be provided)
  • $\begingroup$ This is fantastic, thank you @German C M. Just to clarify, say there is another column called 'Factory', and bag 1 came from Factory-1 and bags 2 and 3 came from Factory-2. And another column called Date, and bags 1 and 3 were made on a Monday but bag 2 was made on a Wednesday. Could we still bootstrap the same way? I know this is a very limited sample, but would we use the same process to explore if there is any significance in either the in the Date or Factory columns? $\endgroup$ – BFG.Digital Aug 14 '20 at 7:26
  • $\begingroup$ I think what you want now is to find out whether there is a statistically significant difference between those groups, depending on when they were manufactured or in which factory. For that, I suggest to carry out a hypothesis testing process, I like the way Allen Downey makes it via permutation test (see greenteapress.com/thinkstats2/html/thinkstats2010.html#sec91); you can also use other tests like ANOVA etc. Btw, if you feel the answer is good enough, you normally give a 'thumb up' and validate it with the tick icon (this way other users can rely on it) $\endgroup$ – German C M Aug 14 '20 at 9:45
  • $\begingroup$ Thanks German C M, I will certainly tick your answer, I really appreciate your time. I haven't quite got my answer. I'm interested to know if this dataset can be bootstrapped correctly by resampling the whole dataset with replacement, or if there are better ways, such as splitting the dataset into "Factory 1" & Factory 2" groups, resampling those two groups with replacement independently and then recombining them, then repeating with Date etc.. so that proportions pertinent to those features can be preserved? $\endgroup$ – BFG.Digital Aug 14 '20 at 11:43
  • $\begingroup$ It depends on what hoy want to find out, e.g. do you want to know if it makes any difference receiving the M&Ms from different factories? I update my answer to indicate what i would do in this case $\endgroup$ – German C M Aug 14 '20 at 13:31
  • $\begingroup$ Thank you so much. $\endgroup$ – BFG.Digital Aug 14 '20 at 13:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.