Compute Statistics with NumPy

Compute statistics with NumPy — lesson 23 in the Data Science with Python track. Learn to calculate mean, median, standard deviation, and more, with hands-on steps and troubleshooting.

Focus: compute statistics with numpy

Sponsored

You have a dataset, but raw numbers are just noise. Without a quick way to summarize them, you're left scanning thousands of rows by eye — and that's a path to errors and wasted hours. The good news: NumPy's statistical functions give you a one-line toolkit to extract the mean, median, spread, and distribution of any array. In this lesson, you'll learn how to compute statistics with NumPy, a skill that turns raw data into actionable insight and forms the foundation of every serious data analysis.

The Problem This Lesson Solves

When you first load a dataset, you're staring at a wall of numbers. How do you make sense of it? The answer is descriptive statistics — numbers that summarize the data into digestible facts. NumPy provides fast, vectorized functions for these measurements, so you can compute statistics on arrays of any size without writing loops.

Without these tools, you'd be tempted to hand-roll your own loops, which are slow and error-prone. NumPy's statistical methods are not only faster (thanks to C-level implementation) but also battle-tested for edge cases like empty arrays and NaN values.

Imagine you're analyzing a year of daily sales figures. You need the average daily sales, the spread (how volatile they are), and whether there's a skewed pattern. Computing these with plain Python would take dozens of lines and be fragile. With NumPy, you can answer all of these in seconds — and that's the core value of this lesson.

Core Concept / Mental Model

Think of NumPy's statistics functions as a summary report builder for your array. Each function looks at the entire dataset and distills it into a single number (or a small set of numbers) that captures one aspect of the data.

Here's a quick analogy: if your array is a class of students' test scores, then:

  • Mean is the class average — a quick measure of overall performance.
  • Median is the score of the middle student — a better measure if one student scored extremely high or low.
  • Standard deviation tells you how much scores differ from the average — whether the class is consistent or scattered.
  • Percentiles let you say, "90% of students scored below this score."
  • Min and max give you the range of the scores.

NumPy's functions operate on entire arrays at once, without loops. This is called vectorization, and it's the key to NumPy's speed and simplicity.

Key NumPy Statistics Functions

  • np.mean() — arithmetic mean (average)
  • np.median() — middle value (robust to outliers)
  • np.std() — standard deviation (spread)
  • np.var() — variance (spread squared)
  • np.min() / np.max() — smallest / largest value
  • np.percentile() — value below which a given percent of data falls
  • np.argmin() / np.argmax() — index of min/max

How It Works Step by Step

  1. Import NumPy — Always start with import numpy as np to access its functions.
  2. Prepare your data — Store your data in a NumPy array (or a list that you convert). np.array() is your friend.
  3. Call the function — Use np.mean(data), np.std(data), etc. They all accept an array as an input.
  4. Pass optional parameters — Many functions support axis, dtype, and keepdims parameters to control behavior (more later).
  5. Interpret results — The output is a NumPy scalar (or array if you use axis), which you can print or use in further calculations.

How Axis Works

For 2D arrays, the axis parameter determines whether you compute statistics across rows or columns:

  • axis=0 — compute down each column (vertically)
  • axis=1 — compute across each row (horizontally)

This lets you compute row-wise or column-wise statistics without reshaping the array.

Hands-On Walkthrough

Let's start with a simple dataset: exam scores for a class of 10 students.

import numpy as np

scores = np.array([78, 85, 92, 64, 88, 71, 96, 59, 83, 90])

mean_score = np.mean(scores)
median_score = np.median(scores)
std_score = np.std(scores)

print(f"Mean: {mean_score:.2f}")
print(f"Median: {median_score:.2f}")
print(f"Standard Deviation: {std_score:.2f}")

Output:

Mean: 80.60
Median: 83.50
Standard Deviation: 10.99

The mean (80.6) is slightly lower than the median (83.5). That suggests a few low outliers pulling the average down — exactly the kind of insight descriptive stats give you.

Using Percentiles and Ranges

# 25th and 75th percentiles
q25 = np.percentile(scores, 25)
q75 = np.percentile(scores, 75)
# Interquartile range (IQR)
iqr = q75 - q25

print(f"25th percentile: {q25:.2f}")
print(f"75th percentile: {q75:.2f}")
print(f"IQR: {iqr:.2f}")
print(f"Range: {np.max(scores) - np.min(scores)}")

Output:

25th percentile: 71.75
75th percentile: 89.50
IQR: 17.75
Range: 37

The IQR tells you the middle 50% of scores span about 17.75 points — a more robust measure of spread than the range, since it ignores extremes.

Working with 2D Arrays and Axis

Now let's compute statistics across a matrix. Suppose we have test scores for three classes, where each row is a class and each column is a student.

# Three classes, five students each
matrix = np.array([
    [88, 72, 91, 85, 79],
    [67, 81, 74, 90, 83],
    [92, 95, 84, 70, 87]
])

# Mean of each class (across columns, axis=1)
class_means = np.mean(matrix, axis=1)
print("Mean per class:", class_means)

# Standard deviation per subject (across rows?), actually across rows axis=0
subject_spread = np.std(matrix, axis=0)
print("Std per column:", subject_spread)

# Overall mean
overall_mean = np.mean(matrix)
print("Overall mean:", overall_mean)

Output:

Mean per class: [83.0 79.0 85.6]
Std per column: [11.14  9.86  7.01  8.29  3.30]

Interpretation: The third class has the highest average (85.6), while the second has the lowest (79.0). The first column (student 1) has the most variation across classes (std 11.14).

Handling Real-World Data with NaN

Real data often contains missing values. By default, np.mean() propagates NaN, but NumPy offers nanmean() and related functions to skip them.

with_nan = np.array([12, 7, None, 15, 9])
# Convert None to NaN (since array creation with None might infer object type)
with_nan = with_nan.astype(float)
with_nan[2] = np.nan

print("Mean (with NaN):", np.mean(with_nan))
print("Mean (skip NaN):", np.nanmean(with_nan))

Output:

Mean (with NaN): nan
Mean (skip NaN): 10.75

Pro tip: Always sanitize your data before analysis. Use nanmean() and friends when you can't clean the data immediately.

Compare Options / When to Choose What

NumPy isn't the only game in town. Here's how it compares to alternatives:

Method Speed Features Best For
NumPy np.mean() Fast (vectorized) Basic stats, axis support Quick calculations on arrays
Python statistics module Slower (Python loops) Some stats, no axis support Small datasets, built-in reliability
pandas df.describe() Fast Full summary table, handling of NaN DataFrames, exploratory analysis
SciPy scipy.stats Requires extra install Advanced stats, distributions Hypothesis testing, advanced stats

When to use what: - Use NumPy when you have raw arrays and need speed and control. - Use pandas when you're working with labeled data (DataFrames) and want a comprehensive summary. - Use SciPy for inferential statistics (like t-tests) that go beyond descriptive stats.

Variations: Robust Statistics

If your data has outliers, the median and IQR are more robust than the mean and standard deviation. NumPy provides np.median() and np.percentile() for this. For seriously skewed data, consider trimming or transforming before computing statistics.

Troubleshooting & Edge Cases

Error: TypeError: 'NoneType' object is not subscriptable

This usually happens when you pass a list that contains None instead of a number. Convert None to np.nan first, or use np.nanmean().

Fix:

data = np.array([1, None, 3], dtype=float)
data[np.isnan(data)] = 0  # optional

Issue: Mean returns nan unexpectedly

If even one element is np.nan, np.mean() returns nan. Use np.nanmean(), or clean the data with data = data[~np.isnan(data)].

Issue: Incorrect results with axis

The most common mix-up: forgetting which axis is rows vs columns. Remember: axis=0 operates down columns (vertical), axis=1 operates across rows (horizontal). Test with a small example if unsure.

Empty arrays raise Mean of empty slice warning

When your array is empty, np.mean() returns nan and prints a runtime warning. Check data.size before computing.

if data.size > 0:
    mean = np.mean(data)
else:
    mean = float('nan')

Overflow or high precision issues

For very large arrays with huge values, np.mean() can cause overflow if dtype is not changed. Use dtype=np.float64 for high precision:

np.mean(large_array, dtype=np.float64)

What You Learned & What's Next

You now have a solid command of computing statistics with NumPy. You can calculate the mean, median, standard deviation, percentiles, and range — both on 1D and 2D arrays — and you understand how to handle missing data and choose between different statistical tools.

Next in the track, you'll take these statistical summaries and turn them into visualizations with Matplotlib, giving you a more intuitive feel for your data's shape and distribution. You'll also start using pandas, where NumPy's statistics become even more powerful when combined with labels.

Keep practicing: open a Jupyter notebook, load a real dataset, and compute its key statistics with NumPy. You're one step closer to mastering data science with Python.

Practice recap

Open a Jupyter notebook and create a NumPy array of 50 random numbers from a normal distribution (use np.random.normal). Compute its mean, median, standard deviation, and the 25th and 75th percentiles. Then add a few extreme outlier values and observe how the median and IQR change versus the mean and standard deviation. This hands-on exercise will solidify your understanding of robust statistics.

Common mistakes

  • Forgetting to convert data to NumPy array before calling stats functions (works with lists, but slower and less efficient).
  • Using np.mean on data containing NaN and getting a nan back instead of the expected number — use np.nanmean instead.
  • Mixing up axis=0 and axis=1 on 2D arrays — axis=0 goes down columns (vertical), axis=1 goes across rows (horizontal).
  • Ignoring the dtype parameter when computing mean of large integers — results may be truncated or overflow; use dtype=np.float64.
  • Forgetting that np.std computes the population standard deviation by default (divide by N), unlike numpy's np.std(ddof=1) for sample standard deviation.

Variations

  1. Use np.nanmean() and related functions to ignore NaN values in arrays — essential for real-world messy data.
  2. Pair NumPy statistics with pandas describe() for a full summary table when working with DataFrames.
  3. Use SciPy's scipy.stats for advanced statistics like skewness, kurtosis, and statistical tests that go beyond NumPy's descriptive tools.

Real-world use cases

  • Analyzing daily sales data to compute average revenue, median order value, and volatility (std) for monthly performance reports.
  • Monitoring server response times by calculating percentiles (p95, p99) to detect latency issues and set SLO targets.
  • Summarizing sensor readings from IoT devices to compute average temperature, spread, and detect abnormal spikes via standard deviation.

Key takeaways

  • NumPy provides fast, vectorized functions like np.mean, np.median, and np.std for computing statistics on arrays.
  • The axis parameter lets you compute row-wise or column-wise statistics on multidimensional arrays.
  • Use np.nanmean and related functions to handle missing values without breaking your analysis.
  • The median and IQR are more robust than the mean and standard deviation when outliers are present.
  • NumPy statistics are the foundation for more advanced data science tools like pandas and SciPy.

Sponsored

Sponsored

Discussion

Questions, corrections, and tips help everyone reading this page.

0 comments

Add a comment

Shown publicly with your comment.

Be constructive · max 4,000 characters

No comments yet — start the thread.

Related tutorials, quizzes, and articles for this topic.