Customer Demographics Analysis Project

Data Analytics project 16

Customer Demographics Analysis Project

Build a complete customer demographics analysis portfolio project with documented metrics, reproducible Python code, validation checks, and responsible interpretation.

Explore Data Analytics training in VizagView all project ideas

Business question

How are customers distributed across broad age bands and regions while reducing re-identification risk?

Dataset and grain

Two thousand synthetic customers with age, broad region, preferred channel, and annual spend.

Requirements

Python 3.10 or later with numpy and pandas installed.

Method and validation checks

Create explicit non-overlapping age bands, aggregate distinct customers and median spend, flag cells below a minimum count, and suppress their spend statistic.

  • Age bands cover every valid age once
  • Customer counts reconcile to the source
  • Small cells do not expose spend statistics
  • No demographic group is treated as inherently better or worse

Complete Python code

Save the code as da_customer_demographics_analysis.py. Review the stated model and field assumptions before using another dataset.

"""Aggregate synthetic demographics with privacy-aware small-cell suppression."""

from __future__ import annotations

import numpy as np
import pandas as pd


def make_demo_customers(n: int = 2_000, seed: int = 42) -> pd.DataFrame:
    rng = np.random.default_rng(seed)
    return pd.DataFrame({"customer_id": range(1, n + 1), "age": np.clip(rng.normal(36, 12, n).round(), 18, 79).astype(int),
                         "region": rng.choice(["North", "South", "East", "West"], n),
                         "preferred_channel": rng.choice(["Web", "Mobile", "Store"], n, p=[0.42, 0.38, 0.2]),
                         "annual_spend": rng.lognormal(8.0, 0.7, n).round(2)})


def demographic_summary(data: pd.DataFrame, minimum_cell: int = 25) -> pd.DataFrame:
    customers = data.copy()
    customers["age_band"] = pd.cut(customers["age"], [17, 24, 34, 44, 54, 64, 120], labels=["18-24", "25-34", "35-44", "45-54", "55-64", "65+"])
    summary = customers.groupby(["region", "age_band"], observed=True, as_index=False).agg(customers=("customer_id", "nunique"), median_spend=("annual_spend", "median"))
    summary.loc[summary["customers"] < minimum_cell, "median_spend"] = np.nan
    summary["suppressed"] = summary["customers"] < minimum_cell
    return summary


def main() -> None:
    print(demographic_summary(make_demo_customers()).round(2).to_string(index=False))
    print("Synthetic data; suppress small groups and avoid sensitive profiling or discrimination.")


if __name__ == "__main__":
    main()

Build and run the project

Run python da_customer_demographics_analysis.py to create region and age-band counts with small-cell suppression.

  1. Confirm the source grain and field definitions.
  2. Reconcile record counts and additive totals.
  3. Validate rate denominators and date filters.
  4. Review outliers and missing values.
  5. Read the interpretation limits before sharing conclusions.

Expected analytical output

A privacy-aware region and age-band table with customer counts, median spend where permitted, and suppression flags.

Interpretation and responsible-use limits

Even broad demographic data can be sensitive and enable discrimination or re-identification. Use lawful purpose, minimum necessary fields, access controls, consent where required, and fairness review.

Ways to extend the project

Add consent and provenance fields, k-anonymity checks, safe channel summaries, missingness review, representative sampling, and controlled access.

Continue learning Data Analytics

Try the next project, return to the Softenant project library, or explore the Data Analytics course in Vizag for guided SQL, Excel, Power BI, Python, dashboard, and portfolio practice.