Lesson 30 · Supply Chain Operations Analytics
Supplier Performance Metrics in Supply Chain Analytics
In this lesson, we will learn how to analyze and measure supplier performance using real-world supply chain data. Supplier evaluation is critical for…
- CourseSupply Chain Operations Analytics
- Lesson30 of 27
- Video22 min
- FormatJupyter notebook · 19 code cells
What you'll learn
- Understanding Supplier Performance Data
- Data Structure and Key Columns
- Beginner Example 1: Counting Unique Suppliers
- Beginner Example 2: Average Supplier Cost
- Beginner Example 3: Suppliers by Department
- Intermediate Example 1: Supplier Tenure Analysis
- Intermediate Example 2: High-Cost Supplier Identification
- Intermediate Example 3: Supplier Cost per Department
Data
No separate download needed — the notebook creates or downloads everything it uses.
📓 Full notebook
Download .ipynbSupplier Performance Metrics in Supply Chain Analytics#
- In this lesson, we will learn how to analyze and measure supplier performance using real-world supply chain data.
- Supplier evaluation is critical for managing procurement risk and ensuring reliable operations.
- You will build practical, hands-on skills for extracting, interpreting, and applying supplier KPIs from public business datasets.
- We will use Python, pandas, and real supplier datasets to assess delivery, cost, and quality metrics.
import pandas as pd
import numpy as np
import openml
import warnings
warnings.filterwarnings('ignore')
Understanding Supplier Performance Data#
- Supplier performance analysis typically uses data about deliveries, costs, and supplier reliability.
- Your data may include columns for order status, fulfillment times, costs, and supplier identifiers.
- Operations datasets can be large and messy, with missing or ambiguous data.
- Beginners often overlook issues such as date parsing, correct units, or duplicate supplier records.
- Clean, structured data enables trusted supply chain decisions.
dataset = openml.datasets.get_dataset(42125)
df, _, _, _ = dataset.get_data(dataset_format='dataframe')
print(df.shape)
print(df.head(3))
Data Structure and Key Columns#
- Our dataset contains supplier names, salary information, hiring dates, and job titles.
- For supplier metrics, we often select columns representing performance, time periods, and costs.
- Beginners should always check column data types and standardize supplier names.
print(df.columns.tolist())
print(df[['full_name', 'department', '2016_gross_pay_received', 'date_first_hired']].head(5))
df = df.rename(columns={'full_name': 'supplier_name'})
df['date_first_hired'] = pd.to_datetime(df['date_first_hired'], errors='coerce')
print(df[['supplier_name', '2016_gross_pay_received', 'date_first_hired']].head(5))
Beginner Example 1: Counting Unique Suppliers#
- A basic supplier metric is simply how many unique suppliers operate in your supply chain.
- Use pandas to compute unique supplier counts for early insights.
unique_suppliers = df['supplier_name'].nunique()
print(f'Number of unique suppliers: {unique_suppliers}')
Beginner Example 2: Average Supplier Cost#
- Knowing the average cost per supplier helps budgeting and procurement planning.
- We will calculate the mean gross pay received as a proxy for annual supplier cost.
mean_cost = df['2016_gross_pay_received'].mean()
print(f'Average 2016 supplier cost: ${mean_cost:,.2f}')
Beginner Example 3: Suppliers by Department#
- Operations often need to view supplier support by department or location.
- Pivot tables help you summarize suppliers by organization unit quickly.
suppliers_per_dept = df.groupby('department')['supplier_name'].nunique().sort_values(ascending=False)
print(suppliers_per_dept.head(10))
Intermediate Example 1: Supplier Tenure Analysis#
- Assessing how long suppliers have supported your organization can reveal reliability.
- We calculate supplier tenure by comparing hire date to end of 2016.
reference_date = pd.to_datetime('2016-12-31')
df['tenure_years'] = (reference_date - df['date_first_hired']).dt.days / 365.25
print(df[['supplier_name', 'tenure_years']].head(5))
Intermediate Example 2: High-Cost Supplier Identification#
- It is important to identify suppliers with the highest costs for negotiation or risk review.
- We will rank the suppliers by their total gross pay received.
top_cost_suppliers = df.groupby('supplier_name')['2016_gross_pay_received'].sum().sort_values(ascending=False)
print(top_cost_suppliers.head(5))
Intermediate Example 3: Supplier Cost per Department#
- Comparing cost structure by department highlights which units rely most on suppliers.
- We calculate and sort cost by department using groupby.
cost_per_dept = df.groupby('department')['2016_gross_pay_received'].sum().sort_values(ascending=False)
print(cost_per_dept.head(10))
Advanced Example 1: Supplier Diversity by Department#
- Diversity of supplier base can reduce supply chain risk.
- We calculate the proportion of a department's supplier spending with the top supplier.
dept_supplier_spend = df.groupby(['department', 'supplier_name'])['2016_gross_pay_received'].sum().reset_index()
top_supplier_fraction = dept_supplier_spend.groupby('department')['2016_gross_pay_received'].max() / dept_supplier_spend.groupby('department')['2016_gross_pay_received'].sum()
print(top_supplier_fraction.sort_values(ascending=False).head(10))
Advanced Example 2: Trend in Supplier Growth#
- Tracking supplier additions over time can reveal trends in sourcing and procurement strategy.
- We will compute number of suppliers hired each year.
df['year_first_hired'] = pd.to_numeric(df['year_first_hired'], errors='coerce')
supplier_growth = df.groupby('year_first_hired')['supplier_name'].nunique()
print(supplier_growth.sort_index())
Error Handling Example: Missing or Invalid Dates#
- Real world datasets often contain missing or malformed dates.
- We will count records with invalid date_first_hired fields.
missing_dates = df['date_first_hired'].isna().sum()
print(f'Number of suppliers with missing or invalid hire dates: {missing_dates}')
Error Handling Example: Duplicate Supplier Records#
- Duplicates in supplier names can distort metrics such as unique supplier counts.
- We demonstrate how to check for duplicate entries.
duplicates = df.duplicated(subset=['supplier_name', 'department', 'date_first_hired'], keep=False)
print(f'Number of duplicate supplier records: {duplicates.sum()}')
Error Handling Example: Inconsistent Columns or Units#
- Supplier cost data may be unintentionally stored as strings or with currency symbols.
- We check for non-numeric entries and convert costs to float.
df['2016_gross_pay_received'] = pd.to_numeric(df['2016_gross_pay_received'], errors='coerce')
print(f'Number of invalid supplier cost entries: {df["2016_gross_pay_received"].isna().sum()}')
Best Practice: KPI Calculation and Reporting#
- Reliable supply analytics start with clean, aggregated data.
- We will create a simple cost and tenure dashboard per supplier.
kpi_df = df.groupby('supplier_name').agg({
'2016_gross_pay_received': 'sum',
'tenure_years': 'max'
}).rename(columns={'2016_gross_pay_received': 'total_cost', 'tenure_years': 'tenure_years'})
kpi_df = kpi_df.sort_values(by='total_cost', ascending=False)
print(kpi_df.head(10))
Best Practice: Time Series Grouping#
- Often, you will need to summarize supplier spend or activity over time.
- We consider cost by year to spot trends and seasonal patterns.
annual_cost = df.groupby('year_first_hired')['2016_gross_pay_received'].sum().sort_index()
print(annual_cost.tail(10))
End-to-End Example: Supplier Risk Heatmap#
- Let us identify top suppliers by cost and tenure for risk-focused supply chain management.
- We will export these results as a table.
risk_table = kpi_df.reset_index().sort_values(['total_cost', 'tenure_years'], ascending=[False, False]).head(20)
risk_table.to_csv('top_supplier_risk_table.csv', index=False)
print(risk_table)
Found this useful?
All lessons, notebooks and datasets here are free. If they helped you, a coffee keeps new lessons coming.



