Ciaren

Sales Data Analysis

A common first task: take a messy export of orders and turn it into a clean revenue summary by region. This walkthrough cleans the data, then groups and aggregates it.

You'll use: File Input → Drop Columns → Change Types → Drop Nulls → Filter Rows → Fill Nulls → Group by + Aggregate → Rename → Sort → File Output.

  1. Input
    File Input
    sales.csv
  2. Clean
    Drop Columns
    remove internal_note
  3. Clean
    Change Types
    amount→float · ordered_at→datetime
  4. Clean
    Drop Nulls
    subset: amount
  5. Clean
    Filter Rows
    amount > 0 (remove refunds)
  6. Clean
    Replace Values
    normalise region casing
  7. Clean
    Fill Nulls
    region → "Unknown"
  8. Transform
    Group By + Aggregate
    region · sum(amount) · count(order_id)
  9. Clean
    Rename Columns
    amount→total_sales · order_id→num_orders
  10. Clean
    Sort Rows
    total_sales desc
  11. Output
    File Output
    sales_summary.csv

Sample data

Save this as sales.csv and upload it on the Datasets page (📥 download sales.csv):

csv
order_id,region,amount,ordered_at,internal_note
1001,North,120.50,2024-01-03,batch-a
1002,south,89.00,2024-01-03,batch-a
1003,North,,2024-01-04,batch-b
1004,South,-5.00,2024-01-04,refund
1005,,42.25,2024-01-05,batch-b
1006,north,210.00,2024-01-06,batch-c

Notice the problems: an internal column we don't want, mixed-case regions, a missing amount, a negative (refund) amount, and a missing region.

Build the flow

  1. File Input — File type CSV, select the sales.csv dataset.
  2. Drop Columns — columns: ["internal_note"].
  3. Change Types — casts: { "amount": "float", "ordered_at": "datetime" }.
  4. Drop Nulls — subset: ["amount"] (drop rows with no amount).
  5. Filter Rows — column: "amount", operator: ">", value: 0 (drop refunds).
  6. Replace Values — tidy region casing, e.g. column: "region", to_replace: "north", value: "North" (add a second node for "south" → "South").
  7. Fill Nulls — strategy: "constant", value: "Unknown", columns: ["region"].
  8. Group by + Aggregate — group_by: ["region"], aggregations: { "amount": "sum", "order_id": "count" }.
  9. Rename Columns — mapping: { "amount": "total_sales", "order_id": "num_orders" }.
  10. Sort Rows — columns: ["total_sales"], ascending: false.
  11. File Output — format: csv (name sales_summary).

Use the live preview after each node to watch the data take shape, then Run the flow.

Exported Python

Click Export → Python. The generated pandas script is standalone — the input frame is named after your dataset, and on a straight chain like this one, consecutive steps fuse into fluent method chains on that single variable:

python
import pandas as pd

df_sales = pd.read_csv('sales.csv')

df_sales = (
    df_sales.drop(columns=['internal_note'])
    .assign(amount=lambda _d: _d['amount'].astype('float64'), ordered_at=lambda _d: pd.to_datetime(_d['ordered_at']))
    .dropna(subset='amount')
    .loc[lambda _d: _d['amount'] > 0]
    .assign(region=lambda _d: _d['region'].replace('north', 'North'))
    .assign(region=lambda _d: _d['region'].replace('south', 'South'))
    .fillna({'region': 'Unknown'})
    .groupby('region')
    .agg({'amount': 'sum', 'order_id': 'count'})
    .reset_index()
    .rename(columns={'amount': 'total_sales', 'order_id': 'num_orders'})
    .sort_values('total_sales', ascending=False)
)

df_sales.to_csv('sales_summary.csv', index=False)

Ciaren also generates the polars equivalent — pick whichever you prefer.

Result

The flow transforms the raw messy CSV into a clean revenue summary.

Full flow
Before
order_idregionamountordered_atinternal_note
1001North120.52024-01-03batch-a
1002south892024-01-03batch-a
1003Northnull2024-01-04batch-b
1004South-52024-01-04refund
1005null42.252024-01-05batch-b
1006north2102024-01-06batch-c
6 rows · 5 cols
After
regiontotal_salesnewnum_ordersnew
North330.52
South891
Unknown42.251
3 rows · 3 cols

The refund row (amount = -5) and the missing-amount row were filtered out; the row with no region became Unknown.

Variations

  • Want revenue per day? Add Extract Date Parts on ordered_at and group by the new ordered_at_day column.
  • Want a recurring summary? Attach a schedule to run this flow every morning.

Next steps