保留正文与补采附件。源页面当前未重新核验;具体限制见交付清单。

Revisit consent button We value your privacy We use cookies to enhance your browsing experience, serve personalised ads or content, and analyse our traffic. By clicking "Accept All", you consent to our use of cookies. Customise Reject All Accept All Customise Consent Preferences We use cookies to help you navigate efficiently and perform certain functions. You will find detailed information about all cookies under each consent category below. The cookies that are categorised as "Necessary" are stored on your browser as they are essential for enabling the basic functionalities of the site. ... Show more NecessaryAlways Active Necessary cookies are required to enable the basic features of this site, such as providing secure log-in or adjusting your consent preferences. These cookies do not store any personally identifiable data.

Functional Functional cookies help perform certain functionalities like sharing the content of the website on social media platforms, collecting feedback, and other third-party features.

Analytics Analytical cookies are used to understand how visitors interact with the website. These cookies help provide information on metrics such as the number of visitors, bounce rate, traffic source, etc.

Performance Performance cookies are used to understand and analyse the key performance indexes of the website which helps in delivering a better user experience for the visitors.

Advertisement Advertisement cookies are used to provide visitors with customised advertisements based on the pages you visited previously and to analyse the effectiveness of the ad campaigns.

Uncategorised Other uncategorised cookies are those that are being analysed and have not been classified into a category as yet. No cookies to display. Reject All Save My Preferences Accept All Toggle SearchToggle Mobile Navigation Publish AI, ML & data-science insights to a global community of data professionals. Sign inSubmit an Article LatestEditor's PicksNewsletterShipAI


Write For TDS LinkedInXToggle Search Programming

EDA in Public (Part 1): Cleaning and Exploring Sales Data with Pandas

Learn how to clean messy CSVs, summarize data, and visualize basic trends in e-commerce sales. Ibrahim Salami December 12, 202510 min read Exploratory Data Analysis with Pandas Image by Author. Created with Gemini Hey everyone! Welcome to the start of a major data journey that I’m calling “EDA in Public.” For those who know me, I believe the best way to learn anything is to tackle a real-world problem and share the entire messy process — including mistakes, victories, and everything in between. If you’ve been looking to level up your Pandas and data analysis skills, this is the series for you. We’re going to act as data analysts for a fictional, mid-sized e-commerce company I’ll call NovaShop. They handed us a raw, messy sales CSV and asked a simple question: “How are we doing?” The goal of Part 1 is foundational: we’ll clean this challenging e-commerce dataset, explore its basic structure, and master the core EDA skills in Pandas that every data scientist uses on a daily basis. This series is structured to take you from a beginner (Part 1) to an advanced data analyst (Part 3), so feel free to jump in wherever you’re at. Before we jump into the code, let’s nail down our core motivation. For NovaShop, we need to answer some simple, yet powerful questions: Which products drive the most revenue? Which countries generate the most sales? Let’s find out. Learn this step by step with the interactive Computer Science roadmap.

Dataset Overview: Unpacking the Sales Data

To start our analysis for NovaShop, we’ll be using the UCI Online Retail Dataset. This is a great, highly realistic, non-streamlined dataset that captures all transactions for a UK-based non-store online retail company between late 2010 and late 2011. This dataset is licensed under a Creative Commons Attribution 4.0 International (CC BY 4.0) license. This allows for the sharing and adaptation of the datasets for any purpose, provided that the appropriate credit is given. The dataset contains over half a million rows, and it’s full of the kinds of anomalies you encounter in the real world — missing values, negative numbers, and inconsistent text formatting. This is exactly what we want! Here are the eight key columns we’ll be working with, and what they tell us from a business perspective:

Let’s take a quick peek at the first few rows to see what we’re dealing with. This is the output of df.head(): Let’s import the dataset into Pandas and see how many rows we’re dealing with. python

import pandas as pd
import numpy as np
df = pd.read_csv(‘Online Retail.csv’)
df.shape

Output: markup

(541909, 8)

That’s quite a lot of rows. I might have to slice the rows a bit.

Data Loading and Slicing: Dealing with Volume

For Part 1, we’re going to take a 10% random sample of the full dataset. This gives us a much more manageable size — around 54,000 rows — while maintaining the characteristics of the original data. This is a common and practical technique when dealing with Big Data environments or when focusing on prototyping. python

# Data Loading and Slicing
FILE_PATH = ‘Online Retail.csv’
SAMPLE_FRACTION = 0.1 # We will sample 10% of the data
full_df = pd.read_csv(FILE_PATH, encoding=’unicode_escape’)

# Take a random 10% sample for faster processing in Part 1
df = full_df.sample(frac=SAMPLE_FRACTION, random_state=42).reset_index(drop=True)

Now, let’s check out the shape again using the df.shape Output: markup

(54191, 8)

Perfect! Now we can begin.

Initial Data Inspection: Getting Our Hands Dirty

My first step will be to discover what we're cleaning. I need to answer these questions

Visual Check: df.head() and df.tail()

Looking at the first and last few rows, I could confirm a few things:

What Are the Data Types and Non-Null Counts? (.info())

The next essential step is to check the structure using the .info() method. This tells me the data type of each column and, most importantly, how many non-null (not missing) values we have. Key Findings

What Do the Numbers Look Like? (.describe())

Next, I used .describe() to get a quick statistical summary of all the numerical columns (Quantity and UnitPrice).

Based on these quick inspections performed.This data is far from clean. We have massive missingness, incorrect data types, highly problematic negative/zero values in our core numerical columns, and text inconsistencies to tackle.

Handling Missing Values

Now that we know where our data is missing, we can begin discussing strategies for handling null values. I’m mostly concerned with Description and CustomerID.

Missing Descriptions

The Description tells us what product was sold, so losing it renders the transaction meaningless. In our sample, less than 1% of the rows have descriptions missing. Dropping those rows completely makes sense, as they are useless for analysis at the product level. python

# Drop rows where the Description is missing
df.dropna(subset=['Description'], inplace=True)
# checking for null counts
df['Description'].isnull().sum()

Output: markup

np.int64(0)

Alright, perfect! All null values are gone.

Missing Customer IDs

The missing CustomerIDs (around 25% of our sample) are a much bigger deal. If I drop all of them, I’ll lose almost a quarter of our sales data, which will give NovaShop a dangerously skewed view of its total revenue. For simple revenue and product analysis (the goal of Part 1), I don’t really need the CustomerID. We can proceed with the analysis on all rows even without an ID. We only need the ID if we plan on doing customer segmentation (like RFM analysis), which I’ll save for Part 2!

Data Type Conversion and Duplicate Removal

Now that we’ve handled the missing descriptions, the next two immediate issues are dealing with fully duplicated rows and fixing our essential InvoiceDate column.

Fixing the Invoice Date Type

Remember how .info() showed InvoiceDate as a string (object)? We need to fix this immediately so Pandas knows how to sort and aggregate our data chronologically. python

# Convert InvoiceDate from object (string) to datetime
df[‘InvoiceDate’] = pd.to_datetime(df[‘InvoiceDate’])

Removing Duplicates

If two rows are identical across all columns, they are duplicates and will artificially inflate our sales numbers. Let’s check for them and remove them. python

# Remove Duplicates
num_duplicates = df.duplicated().sum()
print(f”Found {num_duplicates} fully duplicated rows.”)

Output: markup

Found 62 fully duplicated rows

Let’s drop them python

# Remove duplicates, keeping the first instance
df.drop_duplicates(inplace=True)
print(f”Dataframe size after removing duplicates: {len(df)} rows.”)

Output: markup

Dataframe size after removing duplicates: 53980 rows.

Filtering Out Returns and Errors

Our .describe() method showed us some serious red flags: negative quantities (returns) and zero/negative unit prices (errors/free items). For Part 1, we want to calculate net revenue from sales , so we must filter this noise out.

Handling Negative Quantities and Prices

We will keep only the transactions where:

python

# Filter: Keep only transactions where Quantity is positive (i.e., sales, not returns)
df = df[df[‘Quantity’] > 0]

# Filter: Keep only transactions where UnitPrice is positive (i.e., not free or an error)
df = df[df[‘UnitPrice’] > 0]
print(f”Dataframe size after filtering: {len(df)} rows.”)

Output markup

Dataframe size after filtering: 52933 rows.

Cleaning Text Columns

Finally, let’s tackle those text standardization issues we spotted visually, like the EIRE country code and any potential hidden whitespace in Description.

python

# Cleaning Text Columns
# Clean Description and Country columns
df[‘Description’] = df[‘Description’].str.strip()
df[‘Country’] = df[‘Country’].str.strip()

# Handle specific country name inconsistencies
# EIRE is a common inconsistency in this dataset for Ireland
df[‘Country’].replace(‘EIRE’, ‘Ireland’, inplace=True)
print(“Text columns cleaned and standardized.”)

Feature Engineering & First Insight

The data is now clean. Now we can finally start asking the fun questions. The single most important metric for any sales dataset is revenue. Since our original data only has Quantity and UnitPrice, we need to engineer the Revenue column ourselves.

Feature Engineering: Creating the Revenue Column

Revenue for a transaction is simply the number of items sold multiplied by the price of each item. python

df[‘Revenue’] = df[‘Quantity’] * df[‘UnitPrice’]

First Insight: Which Countries Drive Revenue?

Let’s use our clean data to answer NovaShop’s question: “Which countries are driving our sales?”
We’ll use a powerful three-step combination:

python

# Group by Country, sum the Revenue, and sort for the top 10
top_countries = df.groupby(‘Country’)[‘Revenue’].sum().sort_values(ascending=False).head(10)
print(“\n — — Top 10 Countries by Revenue (GBP) — -”)
print(top_countries)

Output: markup

--- Top 10 Countries by Revenue (GBP) ---CountryUnited Kingdom 941268.661Netherlands 27435.830EIRE 26066.000France 23645.330Germany 22389.510Australia 12429.990Spain 5600.900Switzerland 5483.890Hong Kong 3597.850Belgium 3593.510Name: Revenue, dtype: float64

The output for this typically shows a massive dominance by the United Kingdom. This is expected since the company is UK-based. The next several countries give us a quick roadmap of where NovaShop’s international focus should be.

Conclusion

We did it. We took a raw, half-a-million-row dataset, sliced it for manageability, battled missing values, fixed data types, filtered out errors, and calculated our first key business metric. The hard, foundational work is done. Here’s a quick recap of what we conquered in Part 1:

The clean dataset is now primed for more sophisticated analysis. In Part 2, we’re going to dive deep into Product Analysis and Time-Series Decomposition. We’ll figure out which items are the true money-makers and analyse how sales volume changes hour-by-hour and month-by-month. I’m excited to keep going! If you enjoyed this article. Feel free to let me know on any of these channels. Your feedback will mean a lot to me.

Medium LinkedIn Twitter YouTube

Register Now to Continue Reading

Unlock Towards Data Science with a Free Account

All articles on Towards Data Science are available to registered users. Create a free account today to access this article and thousands more. Register for freeSign in to your account


Written By

Ibrahim Salami

See all from Ibrahim Salami Data AnalyticsData ScienceEda In PythonExploratory Data AnalysisPython Share This Article

Towards Data Science is a community publication. Submit your insights to reach our global audience and earn through the TDS Author Payment Program. Write for TDS

Related Articles

Why Should We Bother with Quantum Computing in ML?

Quantum Computing Quantum Machine Learning principles Erika Gomes-Gonçalves October 22, 202514 min read

Using Function Decorators in Python

Learn how to extend the functionalities of function by using function decorators In this article,... Wei-Meng Lee June 1, 20215 min read

How to Find Korean Actors for Binge-Watching with Machine Learning

Machine Learning Let Me Find You The Closest Actors to Your Favourite Korean Actor Intan Dea Yutami December 6, 20216 min read

Pandas Minesweeper 101

Machine Learning Lookout for these hurdles before diving deep into pandas Sahithya Swaminathan November 27, 20205 min read

Creating the CitySpire App: My Journey

Data Science My Journey About the Project In the last eight weeks, I was a part of... Sweta Sengupta April 28, 20217 min read

Oktoberfest : Quick analysis using Pandas, Matplotlib, and Plotly

Data Science Oktoberfest 2019 has started! Oktoberfest is the world's largest beer festival and is held annually in Munich since 1810. It lasts... Amanda Iglesias Moreno September 22, 201910 min read

Inventory Management for Retail – Deterministic Demand

Data Science Build a simple model to simulate the impact of several replenishment rules on inventory and ordering costs. Samir Saci October 5, 20211 min read

How I Learned Tableau in 1 Day

Data Science From installing the software to delivering a dashboard Arunn Thevapalan June 24, 20204 min read

How To Remove Punctuation From Pandas

Machine Learning Showcasing different ways for eliminating punctuation from pandas DataFrame columns Giorgos Myrianthous April 12, 20225 min read

Your home for data science and AI. The world's leading publication for data science, data analytics, data engineering, machine learning, and artificial intelligence professionals. Subscribe to Our NewsletterWrite For TDS•About•Advertise•Privacy Policy•Terms of Use © Insight Media Group, LLC 2026•The New Stack•roadmap.sh•Creator Network

Recommended Articles

Close