How to Use NumPy for Data Sampling

How to Use NumPy for Data Sampling

Data sampling is the process of selecting a subset of items from a larger group (population) to collect or analyze data. It allows researchers and analysts to make inferences about a larger dataset by working with a smaller, representative portion. This approach is particularly useful when:

  • Working with very large datasets where processing all data would be time-consuming or computationally expensive
  • Testing analytical methods or machine learning models before scaling to full data
  • Validating results using different subsets of data
  • Creating training and testing sets for machine learning applications

NumPy provides several methods for data sampling. In this article, we’ll explore different sampling techniques including random sampling, stratified sampling, and bootstrapping. 

1. Simple Random Sampling with NumPy

Simple random sampling involves selecting a subset of data points randomly from a larger dataset, where each point has an equal probability of being chosen. Let’s look at an example of how to do this with NumPy.

import numpy as np

# Set random seed for reproducibility
np.random.seed(42)

# Dataset of 100 numbers
data = np.arange(1, 101)

# Randomly sample 10 data points
sample = np.random.choice(data, size=10, replace=False)

# Print the sampled data
print("Sampled data:", sample)

Output:

Sampled data: [84 54 71 46 45 40 23 81 11  1]

In this example, we first set a random seed for reproducibility, then use np.random.choice() to randomly sample 10 unique values from the dataset without replacement (replace=False). Looking at our sample, we can see that we’ve obtained 10 unique numbers from our dataset of 1-100. The numbers are well-distributed across the range, which is what we’d expect from a random sample. Notice that each number appears only once since we specified replace=False.

2. Sampling with Replacement

In some cases, it is beneficial to sample with replacement, meaning that each selected data point is put back into the pool and can be chosen again. This allows the same data point to appear multiple times in the sample.

# Set random seed for reproducibility
np.random.seed(42)

# Randomly sample 10 data points with replacement
sample_with_replacement = np.random.choice(data, size=10, replace=True)

# Print the sampled data
print("Sampled data with replacement:", sample_with_replacement)

Output:

Sampled data with replacement: [52 93 15 72 61 21 83 87 75 75]

In this case, while we don’t see any repeated values in our particular sample (except for 75), it’s important to note that repetition would be possible and perfectly valid when sampling with replacement. The probability of selecting any number remains constant throughout the sampling process, regardless of whether it has been selected before.

3. Stratified Sampling with NumPy

Stratified sampling involves dividing the population into different strata (groups) and sampling from each stratum. While NumPy doesn’t have a built-in function for stratified sampling, we can achieve it using logical indexing. Let’s look at two common scenarios:

Case 1: Even Distribution

In this case, we have an equal number of elements in each category (50-50 split). This is common in balanced datasets:

# Set random seed for reproducibility
np.random.seed(42)

# Category labels
categories = np.array(['A'] * 50 + ['B'] * 50)

# Split data into two categories
data_a = data[categories == 'A']
data_b = data[categories == 'B']

# Sample 5 points from each category
sample_a = np.random.choice(data_a, size=5, replace=False)
sample_b = np.random.choice(data_b, size=5, replace=False)

# Combine the samples
stratified_sample = np.concatenate([sample_a, sample_b])

print("Category A distribution:", len(data_a), "elements")
print("Category B distribution:", len(data_b), "elements")
print("Stratified sample:", stratified_sample)
print("Sample proportions: A =", len(sample_a)/len(stratified_sample), 
      "B =", len(sample_b)/len(stratified_sample))

Output:

Category A distribution: 50 elements
Category B distribution: 50 elements
Stratified sample: [14 40 31 46 18 80 89 53 97 96]
Sample proportions: A = 0.5 B = 0.5

In this balanced case, we can see that our data is perfectly split between categories A and B (50 elements each). Our sampling maintained this equal distribution, with exactly 5 elements from each category, resulting in the expected 50-50 split (sample proportions of 0.5 for both A and B). This approach ensures that both categories are equally represented in our final sample.

Case 2: Uneven Distribution

Often encounter uneven distributions. For example, we might have a dataset where 70% of the elements belong to Category A and 30% to Category B:

# Set random seed for reproducibility
np.random.seed(42)

# Example with uneven distribution (70-30 split)
categories = np.array(['A'] * 70 + ['B'] * 30)

# Split data into two categories
data_a = data[categories == 'A']
data_b = data[categories == 'B']

# Sample proportionally: 7 points from Category A and 3 points from Category B
sample_a = np.random.choice(data_a, size=7, replace=False)
sample_b = np.random.choice(data_b, size=3, replace=False)

# Combine the samples
stratified_sample = np.concatenate([sample_a, sample_b])

print("Category A distribution:", len(data_a), "elements")
print("Category B distribution:", len(data_b), "elements")
print("Stratified sample:", stratified_sample)
print("Sample proportions: A =", len(sample_a)/len(stratified_sample), 
      "B =", len(sample_b)/len(stratified_sample))

Output:

Category A distribution: 70 elements
Category B distribution: 30 elements
Stratified sample: [23  1 50  5 55 19 11 72 81 75]
Sample proportions: A = 0.7 B = 0.3

In this unbalanced case, our original data has a 70-30 split between categories A and B. Our stratified sampling maintained this exact proportion by taking 7 samples from category A and 3 from category B. The output shows sample proportions of 0.7 and 0.3, perfectly matching our original distribution. This is particularly useful when you want your sample to reflect the natural imbalance in your dataset.

4. Bootstrapping with NumPy

Bootstrapping is a resampling technique where we sample with replacement from the original data to generate multiple datasets. This method is often used to estimate the sampling distribution of a statistic.

# Set random seed for reproducibility
np.random.seed(42)

# Number of bootstrap samples
n_iterations = 1000

# Array to store bootstrap means
bootstrap_means = []

# Perform bootstrapping
for _ in range(n_iterations):
    bootstrap_sample = np.random.choice(data, size=len(data), replace=True)
    bootstrap_means.append(np.mean(bootstrap_sample))

# Convert to NumPy array
bootstrap_means = np.array(bootstrap_means)

# Calculate the mean and standard deviation of bootstrap means
bootstrap_mean = np.mean(bootstrap_means)
bootstrap_std = np.std(bootstrap_means)

# Print the results
print("Bootstrap mean:", bootstrap_mean)
print("Bootstrap standard deviation:", bootstrap_std)

Output:

Bootstrap mean: 50.44824
Bootstrap standard deviation: 2.890615661481131

These results are quite revealing. Our original dataset consists of numbers from 1 to 100, which has a true mean of 50.5. Our bootstrap estimate of 50.44824 is remarkably close to this true value, demonstrating the power of bootstrapping for estimating population parameters. The relatively small standard deviation (approximately 2.89) indicates that our mean estimate is quite stable across the bootstrap samples. This narrow spread suggests we can be confident in our estimate of the population mean.

Conclusion

Data sampling is an important concept in data analysis, and NumPy provides several efficient methods for performing different types of sampling. In this article, we covered:

  • Simple random sampling with and without replacement
  • Stratified sampling for both balanced and unbalanced datasets
  • Bootstrapping for estimating sampling distributions

Each technique has its own use cases and advantages:

  • Simple random sampling is best for obtaining unbiased samples
  • Stratified sampling helps maintain representation across categories
  • Bootstrapping is valuable for understanding the variability of statistics

For reproducible results, remember to set the random seed using np.random.seed(). If you need more advanced sampling methods or statistical functions, consider using additional libraries like SciPy, pandas, or statsmodels to extend your data analysis capabilities.

Leave a Reply

Your email address will not be published. Required fields are marked *