← Back to portfolio
Former Project ยท Discount Strategy Case Study

Eniac's Discount Strategy:
A Data Cleaning Case Study

Python Pandas Jupyter Matplotlib / Seaborn Plotly

This project started as a messy, real-world dataset from Eniac, an e-commerce electronics retailer, and turned into a deep dive on how much their discounting habit was actually costing them. The dataset was genuinely chaotic โ€” broken price formats, duplicate rows, orders in five different states โ€” so a large chunk of the work was just getting the data into a state I could trust. While preparing this page, I went back and double-checked every number against the source data again, so what's below is verified, not just remembered.

๐Ÿ‘ฅ Built together with Lisa Renn โ€” GitHub

How much is discounting actually costing Eniac?

Eniac is an online electronics retailer selling everything from Apple hardware to accessories, new and second-hand. Acting as internal data analysts, our job was to dig into their order history and figure out how deep the discount habit really went โ€” and what it was doing to revenue.

The data: four linked CSVs โ€” orders, orderlines, products, and brands โ€” covering 437 days, January 1, 2017 to March 14, 2018. Real, non-anonymized, and genuinely messy.

Cleaning a genuinely messy dataset

Before any analysis could happen, the data needed serious work. Here's the pipeline that got it from raw CSVs to something trustworthy:

01Filter to Completed orders. Of 226,909 orders, only 46,605 had state = "Completed" โ€” the rest were abandoned baskets, pending, or cancelled.
02Cross-check orders against orderlines. Kept only orders that existed in both tables, dropping mismatches down to 46,560 orders.
03Drop orders with unknown products. Orderlines referencing a SKU with no match in the product catalog were removed โ€” down to 46,204 orders.
04Remove outliers with the IQR method. Compared each order's paid total against the sum of its line items; anything outside 1.5ร—IQR of that difference got dropped โ€” landing on 45,450 clean orders.
The gnarliest bug

Prices were stored in European formatting, so unit_price and price sometimes read as strings like "1.137.99" instead of 1137.99. A naive fix (just stripping extra dots) mangled some values into nonsense. The real fix had to be positional โ€” check the string length, and remove only the character at the exact index where the thousands-separator dot would sit โ€” leaving the decimal point untouched.

What the clean data showed

01

Discounting isn't occasional โ€” it's the default

94.4%
of orders include a discount
18.4%
median discount size
~100%
maximum discount seen
VerdictAlmost every order gets a discount โ€” this isn't a promotional tactic, it's the standard price of doing business with Eniac.
02

The revenue gap is real, but smaller than first assumed

โ‚ฌ14.0M
actual revenue (discounted)
โ‚ฌ16.4M
revenue at list price
14.6%
revenue given up to discounts
VerdictDiscounting costs Eniac roughly โ‚ฌ2.4M against list price over the period โ€” significant, but a smaller share of revenue than the "discount on almost every order" headline might suggest.
03

Most of the catalog is genuinely affordable

61.7%
of products priced under โ‚ฌ300
VerdictEniac's catalog skews toward accessories and mid-range electronics rather than being dominated by big-ticket items.
04

Second-hand electronics can still command premium prices

25.9%
of second-hand listings priced over โ‚ฌ500
VerdictThere's a real market for premium used electronics โ€” refurbished and open-box items aren't just a clearance bin.
โœ“ All four numbers above were recomputed directly from the raw CSVs during this write-up, following the exact cleaning pipeline documented in the notebooks โ€” not pulled from an earlier draft.

What we recommended

Time discounts deliberately. With discounting this pervasive, timing promotions around genuine demand peaks โ€” rather than running them constantly โ€” could protect margin without losing volume.
Question the reliance on discounting. At 94% of orders, discounting looks less like a lever and more like a crutch. Loyalty programs or bundling could reduce that dependency.
Lean into the premium second-hand market. A quarter of used listings sell for over โ‚ฌ500 โ€” there's real appetite for higher-end refurbished electronics worth building around.

My take

"The biggest lesson from this project wasn't really about discounts โ€” it was about how much a single formatting quirk in raw data can quietly wreck an analysis if you don't catch it. Getting the cleaning pipeline right took longer than the actual discount analysis, and that felt like the real skill being tested." โ€” Iliya, on finishing this project

Tools & workflow

Software
JupyterJupyter
VS CodeVS Code
Coding
PythonPython
NumPyNumPy
PandasPandas
Visualisation
MatplotlibMatplotlib
SeabornSeaborn
PlotlyPlotly
Presenting
MarpMarp
Sharing
GitGit
GitHubGitHub
KaggleKaggle

Notebooks, data & presentation