Generating Mock Sales Data with Python Pandas | by Soner Yıldırım | Towards Data Science

There are several software tools and packages in the data science ecosystem. These tools accelerate the routine processes as well as helping us manage, explore, and analyze data.
Whatever tool you use or whatever project you work on, everything in data science starts from data. Without proper data, your data products are likely to fail.
When studying data science and practicing software tools, it sometimes becomes a challenge to find data to play with. Although there are several free data resources online, they may not always fit your needs.
In this article, we will generate mock sales data using the Pandas library. The data will contain the daily sales data for a chain store. We will use random numbers to assign sales values to stores and products.
The data may not demonstrate the typical features that can be observed in real life sales data such as seasonality or trends. However, you can use it for practicing many tools and techniques.
Moreover, we will be using several Pandas functions and methods when generating the data. Thus, it will also be a good practice for Pandas.
You will have the chance to practice the following topics:
How to create a Pandas data frame
Different ways to create NumPy arrays
Taking a cartesian product of arrays and list
Merging Pandas data frames
Creating line plots with Pandas
Let’s start with importing the libraries needed.
import numpy as npimport pandas as pdfrom random import shuffle
The shuffle module from the random package of Python can be used to shuffle lists.
The next step is to create store and product codes.
store_codes = np.arange(1,10)product_codes = np.arange(1,101)
The store codes start from 1 and go up to 9. We have 100 products starting from 1 and going up to 100.
We also need a date range since this is a time series data. There exist many different methods to perform this task. I will use the date_range function of Pandas.
date_range = pd.date_range(start = "2019-01-01", end = "2020-12-31", freq="D")
Our range covers a period of 2 years. The freq parameter is used for determining the increment size. “D” stands for day so we will have daily sales data for 2019 and 2020.
We have a period of 2 years, 9 stores, and 100 products. For each day, our data will contain a sales amount for each product-store pair. Thus, we need to generate a cartesian product of the date_range, store_codes, and product_codes arrays.
One method is to create a multi index by taking the cartesian product of these arrays. We can then use it for creating a data frame.
index = pd.MultiIndex.from_product(   [date_range, store_codes, product_codes],   names = ["Date", "StoreCode", "ProductCode"])sales = pd.DataFrame(index = index)sales.head()
This is the index of the sales data frame. In order to create columns from this multi index, we just need to use the reset_index function.
sales.reset_index(inplace=True)sales.head()
The sales data frame contains a row for each date, store code, and product code combination. Thus, the number of rows should be equal to the product of the number of items in each array.
len(sales) == len(store_codes) * len(product_codes) * len(date_range)Truelen(sales)657900
We have just confirmed our anticipation. We have a data frame with 657k rows.
It is a common practice to group stores and products in the retail industry. Let’s start with the stores.
store_groups = ["Small","Medium","Large"]*3shuffle(store_groups)stores = pd.DataFrame({   "StoreCode": np.arange(1,10),   "StoreGroup": store_groups})stores
Since there are 9 stores, we have created a list of 9 elements grouped under 3 categories. The shuffle functions shuffles this list in place. Otherwise, the order of the base list will be kept.
We can assign product groups similarly.
product_groups = ["A","B","C","D"] * 25shuffle(product_groups)products = pd.DataFrame({   "ProductCode": np.arange(1,101),   "ProductGroup": product_groups})products.head()
We have 100 different product codes grouped under 4 categories.
We might need to analyze the sales performance of different store and product groups. Thus, these categories need to be merged to the sales data frame.
The merge function of Pandas can be used to accomplish this task.
sales = pd.merge(sales, stores, on="StoreCode", how="left")sales = pd.merge(sales, products, on="ProductCode", how="left")sales.head()
We have reached the final step of data generation which I think is the most important one. We need to add the sales amounts.
Your options are limitless here. A simple method is to create a NumPy array with random integers and add it to the sales data frame.
size = len(sales)sales_amount = np.random.randint(0, 50, size=len(sales))sales["SalesAmount"] = sales_amountsales.head()
The sales amount column consists of random integers between 0 and 50. It is purely random so we cannot observe any trend or seasonality in our sales.
You can save this data frame as a csv file using the to_csv function:
sales.to_csv("mock_sales.csv", header=True, index=False)
Let’s check it by plotting the sales amount of a product store pair. The following code creates a line plot of the sales amount of a particular pair in the last 2 months.
sales[     (sales.StoreCode==1) &     (sales.ProductCode==5) &     (sales.Date > "2020-11-01")     ].plot(x="Date", y="SalesAmount", kind="line", figsize=(10,6))
We can clearly observe the randomness in the sales amounts.
We can be a little more creative while generating the sales amounts. Some random noise or seasonality can be added to the values. I leave that part to you.
We have mock sales data but we haven’t done any exploratory data analysis on it yet. It will be the topic of the following article. Stay tuned!
Thank you for reading. Please let me know if you have any feedback.