Programming for Data Processing

Lectures: Nguyễn Tuấn Phong, Đào Việt Anh

Labs: Trịnh Ngọc Huỳnh, Phạm Tiến Du

Semester: 2025-2026-1

Institute for AI, VNU-UET

Lecture 5
Numpy: Arrays &
Vectorized Computation

1.
NumPy Overview

Why NumPy?

  • Numerical Python: core of scientific computing
  • ndarray: standard array interface in Python ecosystem
  • Foundation for tools like pandas, SciPy, scikit-learn

Historical Note

  • 1995: Numeric library (Jim Hugunin)
  • 2000s: fragmented array libraries
  • 2005: NumPy unified Numeric + Numarray (Travis Oliphant)

What NumPy Provides

  • ndarray: fast multidimensional arrays with broadcasting
  • Vectorized math functions (no loops needed)
  • I/O tools: read/write arrays, memory-mapped files
  • Linear algebra, random number generation, Fourier transforms
  • C API for integration with C/C++/FORTRAN

Why It Matters

  • Interoperability with compiled libraries via C API
  • Wrap legacy C/C++/FORTRAN code with Python interfaces
  • Understanding array semantics makes pandas & SciPy easier

Why NumPy is Fast

  • Contiguous memory layout → efficient storage
  • C-level algorithms → less interpreter overhead
  • Vectorized operations → avoid slow Python loops

Performance Demo: NumPy vs List

💡 NumPy is >100× faster than lists in this operation!

2.
The NumPy ndarray

The ndarray Object

  • ndarray = N-dimensional array
  • Multidimensional, homogeneous array of fixed-size items
  • Fast, flexible container for large datasets
  • Supports vectorized math on entire arrays (no loops!)
  • Syntax similar to scalar operations in Python

How NumPy Stores Data

  • Homogeneous data type → fixed-size elements
  • Single contiguous (or strided) memory buffer
  • ndarray = metadata (shape, strides, dtype) + data buffer → efficient access
  • Python list = pointers to separate objects → scattered in memory
Contiguous buffer (fixed-size elements)
NumPy ndarray
List of pointers → scattered objects
Python list

ndarray: Create → Operate → Inspect

Convention

  • Always use import numpy as np
  • Avoid from numpy import *
    • Namespace conflicts with Python's built-in functions (min, max)

2.1.
Creating ndarray

Creating ndarray

  • np.array: from lists or sequences
  • Nested sequences → multidimensional arrays
  • Shape and dtype inferred automatically

Examples

Simple list → 1D array:

Nested list → 2D array:

NumPy tries to infer data types automatically:

Array Constructors

  • np.zeros, np.ones

Array Constructors

  • np.empty (uninitialized values)
  • Use only when filling values immediately: empty_array[:] = 42

Array Constructors

  • np.arange (like built-in range)
  • Supports non-integer steps
  • More flexible than built-in range

Array Constructors

For more special constructors, see:
Table: NumPy array creation functions

2.2.
Data Types

Data Types

  • dtype tells NumPy how to interpret memory
  • Common: float64, int32, bool, object
  • Controls memory, I/O, interoperability, speed

Specifying & Inspecting dtypes

Casting with astype

Integers to floats

Strings to numeric

  • astype always makes a copy
  • ⚠️ Fixed-size np.string_ may truncate input

2.3.
Arithmetic with Arrays

Element-wise Ops

Arithmetic operations on arrays apply element-wise

Between arrays of the same size:

Element-wise Ops

Arithmetic operations on arrays apply element-wise

Between arrays and scalars:

Comparisons

Comparisons between arrays of the same size yield Boolean arrays:

2.4.
Indexing & Slicing: Basics

1D Indexing

  • Syntax similar to Python lists/tuples
  • But: Slice = view, not copy
    • 💡 Assign to slice modifies original array

More on: Slice = view

Use : to modify the entire array:

Copy a Slice

Use .copy() to make a copy of a slice

2D Indexing

Elements at each index are one-dimensional arrays

2D Indexing

Individual elements can be accessed recursively:

Or using a comma-separated tuple of indices:

2D Indexing

Think of axis 0 as the rows and axis 1 as the columns.

Axis 1 0 1 2 Axis 0 0 1 2 0,0 0,1 0,2 1,0 1,1 1,2 2,0 2,1 2,2

3D Indexing

3D Indexing

Omitting later indices → return a lower dimensional ndarray

Broadcast Assignment to a Slice

Assign a scalar value:

Broadcast Assignment to a Slice

From another array:

Indexing with Slices

1D Arrays

1D arrays can be sliced with the : operator.

Indexing with Slices

2D Arrays

2D arrays can be sliced along both axes.

Indexing with Slices

2D Arrays

Can mix integer indices and slices.

Indexing with Slices

Assignments to Slices

Assignments to slices propagate to the entire selection.

2D Slicing: Illustration

Expression Shape arr[:2,1:] (2,2) arr[2] (3,) arr[2, :] (3,) arr[2:, :] (1,3) Expression Shape arr[:, :2] (3,2) arr[1, :2] (2,) arr[1:2, :2] (1,2)

2.5.
Boolean Indexing

Setup: Names & Data

Building a Boolean Mask

Comparisons are vectorized:

→ This array of Boolean values is called a mask.

Indexing with a Mask

Mask length must match the axis being indexed

Negation

Combine Conditions

Use Boolean arithmetic operators: & (and), | (or).

Note: Boolean selection returns a copy of the data.

Set Values with Masks

Right-hand values broadcast into True positions.

Set Values with Masks

Right-hand values broadcast into True positions.

2.6.
Fancy Indexing

Fancy Indexing

Fancy indexing = indexing with integer arrays.

Setup: 8×4 Array

Pick Rows in Any Order

Pass a list/array of row indices:

Negative indices count from the end:

Index with Multiple Integer Arrays

Pair of index arrays → pick specific tuples (row, col) → 1D result.

Selected (1,0), (5,3), (7,1), (2,2). Arrays must have the same shape.

Select Rectangular Region

To get a row-subset × column-subset rectangle, index rows then index columns:

Copy vs View; Assignment

  • Fancy indexing returns a copy (unlike slicing).
  • But using it on the left-hand side assigns into the original array.

2.7.
Transposing Arrays & Swapping Axes

Transpose Basics

Transposing is a reshape that returns a view (no copy).

Transpose in Matrix Math

Common in inner products / Gram matrices.

More on reshape

See Appendix A: Advanced NumPy for details on reshape.

Swapping Axes

swapaxes(axis1, axis2) generalizes transpose; returns a view.

Swapping axes of a 3D array
Given a 3D array with shape (2, 3, 4), what will be the shape of the array after applying swapaxes(0, 2), swapaxes(1, 2), and swapaxes(0, 1)?
→ Try it out in Jupyter Notebook!

3.
Pseudorandom Number Generation

Why numpy.random?

  • Generate whole arrays of samples efficiently
  • Many distributions: normal, uniform, binomial, beta, …
  • Vectorized & fast vs Python’s random (one value at a time)

Draw Samples

4×4 from standard normal distribution with np.random.standard_normal:

Speed: Python random vs NumPy

💡 NumPy is >20× faster for this large draw.

Modern API: Generator

  • Create an isolated random number generator (RNG) with np.random.default_rng
  • Pass an explicit seed for reproducibility

Common Generator Methods

Method Description
integers(low, high, size) random integers
standard_normal(size) N(0,1)
normal(loc, scale, size) Gaussian
uniform(low, high, size) continuous uniform
binomial(n, p, size) binomial distribution
beta(a, b, size) beta distribution
gamma(shape, scale, size) gamma distribution
chisquare(df, size) chi-square distribution
permutation(x) return a permuted copy
shuffle(x) permute in place

Quick Demos

Best Practices

  • Prefer rng = np.random.default_rng(seed) over legacy np.random.seed
  • Pass rng down into functions for reproducibility
  • Draw arrays directly (avoid Python loops)

More methods: NumPy RNG method table

4.
Universal Functions

Universal Functions (Ufunc)

  • Ufunc = fast, vectorized, element-wise ops on ndarrays
  • Types: Unary (e.g., np.sqrt) and Binary (e.g., np.add)
  • Implemented in C → much faster than Python loops

Unary ufuncs

Take a single array argument and return a single array.

Binary ufuncs

Take two arrays and return a single array.

Multi-Output ufunc

  • Some ufuncs return multiple arrays.
  • E.g., np.modf returns fractional and integral parts.

Writing Results In-Place

  • Use out= argument to write results into a pre-allocated array.
  • Reduces temporary allocations, helpful in memory-sensitive or performance-critical loops.

Some Unary Ufuncs

Function Description
abs, fabs Element-wise absolute value
sqrt Square root (≈ arr ** 0.5)
square Square (≈ arr ** 2)
exp ex element-wise
log, log10, log2, log1p Natural / base-10 / base-2 / log(1+x)
sign Sign of each element (−1, 0, 1)
ceil, floor, rint Round up / down / to nearest (preserves dtype)
modf Fractional and integral parts (returns two arrays)
isnan, isfinite, isinf NaN / finite / infinite checks (Boolean arrays)
cos, sin, tan, … Trig and hyperbolic trig; inverses: arccos, …
logical_not Element-wise NOT (≈ ~arr)

See NumPy docs for a full, up-to-date list.

Some Binary Ufuncs

Function Description
add, subtract, multiply Element-wise arithmetic
divide, floor_divide True division / floor division
power a ** b element-wise
maximum, fmax Element-wise max; fmax ignores NaN
minimum, fmin Element-wise min; fmin ignores NaN
mod Remainder
copysign Copy sign from second arg to first
greater, >=, <, <=, ==, != Comparisons → Boolean arrays
logical_and, logical_or, logical_xor Element-wise logical ops (&, |, ^)

Matrix multiplication uses @ or np.dot (not a ufunc).

5.
Array-Oriented Programming

Vectorization

  • Express data processing as array expressions (avoid Python loops)
  • Broadcasting enables operations on different-shaped arrays
  • Typically much faster than pure Python

Vectorization: Example

Compute $\sqrt{x^2 + y^2}$ with NumPy (‼️ no loops):

Conditional Logic

  • Vectorized ternary: np.where(cond, x, y)
  • x/y can be arrays or scalars

Math & Stats: Aggregations

  • Reduce an array to a single value (or smaller array)
  • E.g.,: mean, sum, std, …
  • Use axis= to reduce across rows/cols

Math & Stats: Aggregations

Example

Math & Stats: Accumulations

  • Compute intermediate results along an axis
  • Returns an array of the same size
  • E.g., cumsum, cumprod

Math & Stats: Accumulations

Example

Basic Statistical Methods

Method Description
sum Total (0 for zero-length)
mean Arithmetic mean (NaN for zero-length)
std, var Std. dev. / variance
min, max Minimum / maximum
argmin, argmax Index of min / max
cumsum Cumulative sum
cumprod Cumulative product

Boolean Arrays

  • Booleans behave like 1/0 in reductions

Boolean Arrays

  • any → any True, all → all True

Sorting

Example

Sorting

Example

Unique & Set Logic

  • Find unique values, common values, set differences, etc.
  • E.g., np.unique, np.in1d

Unique & Set Logic

Example

Find and sort unique values in an array

Find which values in one array are present in another

Array Set Operations

Function Description
unique(x) Sorted unique elements
intersect1d(x, y) Sorted common elements
union1d(x, y) Sorted union
in1d(x, y) Membership test (Boolean mask)
setdiff1d(x, y) Elements in x not in y
setxor1d(x, y) Symmetric difference

6.
Linear Algebra Operations

Matrix Multiplication

Use @ operator (Python 3.5+) or np.dot function.

Matrix–Vector Multiplication

Matrix–vector products are also done with @ or np.dot.

Inverse

Common numpy.linalg Functions

Function Description
dot / @ Matrix multiplication
diag, trace Diagonal / sum of diagonal
det Determinant
eig Eigenvalues & eigenvectors
inv, pinv Inverse / pseudoinverse
qr, svd QR / singular value decomposition
solve, lstsq Solve Ax=b (square / least squares)

Wrap-up

  • NumPy is the foundation of data science in Python
  • Key features: N-dimensional arrays, vectorized operations
  • More advanced NumPy topics: See 1, 2
  • Next: Pandas