cswork / libraryOpen practice workspace

Coding questions · Amazon

Identify Top Spenders and Segment Customers Using Python

This question evaluates proficiency in data manipulation and aggregation using SQL/Python (pandas), covering customer segmentation, monthly grouping and ranking, and reshaping transactional data into a wide format for product-level spend analysis.

orders

+----------+---------+------------+----------+--------------+-------------------+
| order_id | cust_id | order_date | product  | order_amount | shipping_option_id |
+----------+---------+------------+----------+--------------+-------------------+
| 1001     | 200     | 2023-01-02 | camera   | 750          | 2                 |
| 1002     | 201     | 2023-01-05 | shoes    | 80           | 1                 |
| 1003     | 200     | 2023-02-10 | laptop   | 1200         | 2                 |
| 1004     | 202     | 2023-02-15 | clothes  | 45           | 1                 |
| 1005     | 201     | 2023-03-08 | camera   | 700          | 3                 |
+----------+---------+------------+----------+--------------+-------------------+
Scenario

E-commerce order insights – marketing wants to segment customers and find top spenders.

Question

Using Python (pandas), return the list of cust_id who have placed fewer than 2 orders OR have spent less than 100 in total. Write Python code that finds, for each calendar month, the top 5 customers by (a) highest total number of orders and (b) highest total order cost. Produce a wide-format DataFrame: columns = ['cust_id','camera','shoes','laptop','clothes'] where each cell shows how much that customer has spent on the product type.

Hints

Start with groupby aggregations; for the wide table use pivot_table or groupby+unstack.

Identify low-activity customers

Return cust_id values for customers who have placed fewer than 2 orders OR whose total spend is less than 100 across all their orders.

Table orders

columntypeconstraints
order_idINTEGERPRIMARY KEY, NOT NULL
cust_idINTEGERNOT NULL
order_dateDATENOT NULL
productVARCHAR(50)NOT NULL
order_amountDECIMAL(10,2)NOT NULL, CHECK (order_amount >= 0)
shipping_option_idINTEGERNOT NULL

Sample data:

cust_idorder_amountorder_dateorder_idproductshipping_option_id
2007502023-01-021001camera2
201802023-01-051002shoes1
20012002023-02-101003laptop2
202452023-02-151004clothes1
2017002023-03-081005camera3

Expected output

List of customers who either have fewer than 2 total orders or have spent less than 100 overall.

cust_id
202

Hints

  1. Aggregate by cust_id to get order counts and total spend.
  2. Filter using an OR condition on count and sum.

Top 5 by orders monthly

For each calendar month, find the top 5 customers ranked by highest total number of orders; break ties by higher total amount, then lower cust_id.

Table orders

columntypeconstraints
order_idINTEGERPRIMARY KEY, NOT NULL
cust_idINTEGERNOT NULL
order_dateDATENOT NULL
productVARCHAR(50)NOT NULL
order_amountDECIMAL(10,2)NOT NULL, CHECK (order_amount >= 0)
shipping_option_idINTEGERNOT NULL

Sample data:

cust_idorder_amountorder_dateorder_idproductshipping_option_id
2007502023-01-021001camera2
201802023-01-051002shoes1
20012002023-02-101003laptop2
202452023-02-151004clothes1
2017002023-03-081005camera3

Expected output

Top 5 customers per month by number of orders with tie-breakers by total amount and cust_id.

cust_idranktotal_amounttotal_ordersyear_month
200175012023-01
20128012023-01
2001120012023-02
20224512023-02
201170012023-03

Hints

  1. Group by month (DATE_TRUNC) and cust_id.
  2. Use ROW_NUMBER with PARTITION BY month for ranking.

Top 5 by amount monthly

For each calendar month, find the top 5 customers ranked by highest total order amount; break ties by higher order count, then lower cust_id.

Table orders

columntypeconstraints
order_idINTEGERPRIMARY KEY, NOT NULL
cust_idINTEGERNOT NULL
order_dateDATENOT NULL
productVARCHAR(50)NOT NULL
order_amountDECIMAL(10,2)NOT NULL, CHECK (order_amount >= 0)
shipping_option_idINTEGERNOT NULL

Sample data:

cust_idorder_amountorder_dateorder_idproductshipping_option_id
2007502023-01-021001camera2
201802023-01-051002shoes1
20012002023-02-101003laptop2
202452023-02-151004clothes1
2017002023-03-081005camera3

Expected output

Top 5 customers per month by total spend with tie-breakers by order count and cust_id.

cust_idranktotal_amounttotal_ordersyear_month
200175012023-01
20128012023-01
2001120012023-02
20224512023-02
201170012023-03

Hints

  1. Aggregate monthly totals per customer.
  2. Rank by total_amount with ROW_NUMBER and tie-breakers.

Pivot spend by product

Produce a wide-format table with columns ['cust_id','camera','shoes','laptop','clothes'] where each cell is the total amount the customer spent on that product.

Table orders

columntypeconstraints
order_idINTEGERPRIMARY KEY, NOT NULL
cust_idINTEGERNOT NULL
order_dateDATENOT NULL
productVARCHAR(50)NOT NULL
order_amountDECIMAL(10,2)NOT NULL, CHECK (order_amount >= 0)
shipping_option_idINTEGERNOT NULL

Sample data:

cust_idorder_amountorder_dateorder_idproductshipping_option_id
2007502023-01-021001camera2
201802023-01-051002shoes1
20012002023-02-101003laptop2
202452023-02-151004clothes1
2017002023-03-081005camera3

Expected output

One row per customer with total spend per product in separate columns.

cameraclothescust_idlaptopshoes
750020012000
7000201080
04520200

Hints

  1. Use conditional aggregation with CASE WHEN.
  2. Sum per product and group by cust_id.