Customer Segmentation
Customer Segmentation
Group customers into spending tiers by combining two files: a customer list and an order history. This shows off Join, Group by + Aggregate, and Bin Column.
You'll use: two File Inputs → Group by + Aggregate → Rename → Join → Bin Column → Sort → File Output.
The key pattern here is a fork-join: two separate File Input nodes feed into a single Join node. The left branch aggregates orders first; the right branch is the raw customer list.
Sample data
customers.csv:
customer_id,name,country
1,Ada,UK
2,Grace,US
3,Linus,FI
4,Margaret,US
orders.csv:
order_id,customer_id,amount
5001,1,40.00
5002,1,60.00
5003,2,500.00
5004,3,15.00
5005,4,220.00
5006,4,30.00
Upload both on the Datasets page (📥 download customers.csv · orders.csv).
Build the flow
- File Input (orders) — File type CSV, select
orders.csv. - Group by + Aggregate —
group_by: ["customer_id"],aggregations: { "amount": "sum", "order_id": "count" }. One row per customer with their total spend and order count. - Rename Columns —
mapping: { "amount": "total_spent", "order_id": "num_orders" }. - File Input (customers) — File type CSV, select
customers.csv. - Join — connect the renamed aggregate to the left handle and the
customers input to the right handle. Config:
on: "customer_id",how: "left". - Bin Column —
column: "total_spent",new_column: "tier",bins: 3,method: "equalwidth",labels: ["Bronze", "Silver", "Gold"]. - Sort Rows —
columns: ["total_spent"],ascending: false. - File Output —
format: csv(namesegments).
Exported Python
import pandas as pd
df_orders = pd.read_csv('orders.csv')
df_customers = pd.read_csv('customers.csv')
df_orders = (
df_orders.groupby('customer_id')
.agg({'amount': 'sum', 'order_id': 'count'})
.reset_index()
.rename(columns={'amount': 'total_spent', 'order_id': 'num_orders'})
)
df_1 = df_orders.merge(df_customers, on='customer_id', how='left')
df_1 = (
df_1.assign(tier=pd.cut(df_1['total_spent'], bins=3, labels=['Bronze', 'Silver', 'Gold']).astype('string'))
.sort_values('total_spent', ascending=False)
)
df_1.to_csv('segments.csv', index=False)
Each input frame is named after its dataset; straight-line steps reuse one
variable, while the join's two inputs keep their own (df_orders,
df_customers) because both must still exist when pd.merge runs.
Result
Each customer now has their total spend, order count, and assigned tier.
| order_id | customer_id | amount |
|---|---|---|
| 5001 | 1 | 40 |
| 5002 | 1 | 60 |
| 5003 | 2 | 500 |
| 5004 | 3 | 15 |
| 5005 | 4 | 220 |
| 5006 | 4 | 30 |
| customer_id | name | country | total_spentnew | num_ordersnew | tiernew |
|---|---|---|---|---|---|
| 2 | Grace | US | 500 | 1 | Gold |
| 4 | Margaret | US | 250 | 2 | Silver |
| 1 | Ada | UK | 100 | 2 | Bronze |
| 3 | Linus | FI | 15 | 1 | Bronze |
Tips
- Quantile vs. equal-width bins.
quantileputs roughly equal counts of customers in each tier;equalwidthsplits the value range evenly. Choose based on whether you care about ranking or absolute thresholds. - Key names differ? If the join columns aren't both named
customer_id, useleft_onandright_onon the Join node instead ofon.