cswork / libraryOpen practice workspace

Coding questions · Boston Consulting Group

Visualize and Clean SKU Sales Data for Outliers

This question evaluates data manipulation and exploratory data analysis skills, including aggregation, outlier detection (IQR/Z-score) and visualization using Python libraries such as pandas and matplotlib/seaborn.

sales_data

+------------+--------+-----------+----------+------------+---------+
| date       | sku_id | unit_sold | revenue  | promo_flag | store_id|
+------------+--------+-----------+----------+------------+---------+
| 2023-01-01 | A123   | 120       | 2400.00  | 1          | S01     |
| 2023-01-02 | A123   | 80        | 1600.00  | 0          | S01     |
| 2023-01-01 | B456   | 200       | 3000.00  | 1          | S02     |
| 2023-01-02 | B456   | 50        | 750.00   | 0          | S02     |
Scenario

Codesignal live-coding: analyst receives raw daily SKU sales data and must explore it visually while cleaning extreme values.

Question

Using Python (pandas, matplotlib/seaborn), draw a histogram of daily revenue per SKU and identify outliers with the IQR or Z-score method. Remove the detected outliers and re-plot the cleaned distribution.

Hints

Focus on reproducible pandas pipeline: load → aggregate → detect outliers → filter → visualize before/after.

Flag Daily Revenue Outliers Per SKU Using IQR

You are given raw daily SKU sales data at the transaction level. Write a SQL query that:

  1. Aggregates revenue to the level of (date, sku_id) as daily_revenue.
  2. For each sku_id, computes the 25th percentile (Q1) and 75th percentile (Q3) of daily_revenue using percentile_cont.
  3. Derives the IQR-based outlier bounds: lower_bound = Q1 - 1.5 * (Q3 - Q1) and upper_bound = Q3 + 1.5 * (Q3 - Q1).
  4. Flags each (date, sku_id) daily_revenue as an outlier if it falls outside these bounds. Return one row per (date, sku_id) with the daily_revenue, Q1, Q3, lower_bound, upper_bound, and a boolean is_outlier flag.

Table sales_data

columntypeconstraints
dateDATENOT NULL
sku_idVARCHAR(10)NOT NULL
unit_soldINTEGERNOT NULL, CHECK (unit_sold >= 0)
revenueDECIMAL(12,2)NOT NULL, CHECK (revenue >= 0)
promo_flagINTEGERNOT NULL, CHECK (promo_flag IN (0,1))
store_idVARCHAR(10)NOT NULL

Sample data:

datepromo_flagrevenuesku_idstore_idunit_sold
2023-01-0112400A123S01120
2023-01-0201600A123S0180
2023-01-0113000B456S02200
2023-01-020750B456S0250

Expected output

A per-date, per-SKU aggregation of revenue with per-SKU IQR-based bounds and a boolean flag indicating whether each daily_revenue value is an outlier. For the provided sample data, no outliers are detected; the cleaned distribution equals the original.

daily_revenuedateis_outlierlower_boundq1q3sku_idupper_bound
24002023-01-01false120018002200A1232800
16002023-01-02false120018002200A1232800
30002023-01-01false-3751312.52437.5B4564125
7502023-01-02false-3751312.52437.5B4564125

Hints

  1. First aggregate to daily revenue per SKU: SELECT date, sku_id, SUM(revenue) AS daily_revenue FROM sales_data GROUP BY date, sku_id.
  2. Use percentile_cont(0.25) and percentile_cont(0.75) WITHIN GROUP (ORDER BY daily_revenue) over each sku_id to compute Q1 and Q3.
  3. Compute IQR = Q3 - Q1 and define lower_bound = Q1 - 1.5 * IQR, upper_bound = Q3 + 1.5 * IQR.
  4. Flag outliers as daily_revenue values outside [lower_bound, upper_bound]; this flagged dataset can then be exported to Python for before/after histograms.