Array-Oriented Programming with NumPy
ndarray, which this chapter simply calls an array. The chapter then introduces pandas Series and DataFrame collections for more flexible data analysis.What You Will Learn
- Create NumPy arrays from existing data and ranges.
- Understand array dimensions, shape, size and element type.
- Create arrays filled with zeros, ones or a specified value.
- Compare list and array performance with IPython
%timeit. - Perform arithmetic on entire arrays using array-oriented programming.
- Understand broadcasting.
- Use NumPy calculation methods such as
sum,min,max,mean,stdandvar. - Use NumPy universal functions.
- Index and slice one- and two-dimensional arrays.
- Understand shallow views versus deep copies.
- Reshape and transpose arrays.
- Use pandas
SeriesandDataFramefor data-science tasks.
Chapter Structure
7.1 Introduction
NumPy means Numerical Python. It provides a high-performance, richly functional n-dimensional array type called ndarray. In this chapter, we use the shorter word array.
The important difference from a normal Python list is that NumPy is designed for efficient numerical array processing. The book notes that many array operations can be up to two orders of magnitude faster than corresponding list operations, which can matter greatly when processing large datasets.
General-purpose collection
Very flexible, good for many everyday tasks.
Numerical, multidimensional collection
Optimized for fast array-oriented calculations.
Array-Oriented Programming
With a list, you often write a loop yourself to process every element. NumPy lets you write an operation once and apply it to an entire array.
This style is concise and can reduce the kinds of bugs that occur when manually writing many external loops.
7.2 Creating Arrays from Existing Data
The usual convention is:
import numpy as npThe alias np lets you write np.array, np.arange, np.zeros, and so on.
Creating an Array from a List
import numpy as np
numbers = np.array([1, 2, 3, 4, 5])
print(numbers)[1 2 3 4 5]Creating a Two-Dimensional Array
grades = np.array([
[87, 96, 70],
[100, 87, 90],
[94, 77, 90]
])
print(grades)[[ 87 96 70]
[100 87 90]
[ 94 77 90]]Here we have 3 rows × 3 columns.
7.3 array Attributes
NumPy arrays have attributes that describe their structure and stored data.
| Attribute | Easy meaning |
|---|---|
ndim | Number of dimensions |
shape | Size of each dimension |
size | Total number of elements |
dtype | Type of elements stored in the array |
itemsize | Number of bytes used by each element |
integers = np.array([[1, 2, 3], [4, 5, 6]])
print(integers.ndim)
print(integers.shape)
print(integers.size)
print(integers.dtype)2
(2, 3)
6
int64How to Think About These Attributes
Iterating Through Multidimensional Arrays
You can use nested loops when you need external iteration:
for row in integers:
for value in row:
print(value, end=' ')NumPy also provides the flat attribute to iterate through all elements as if the array were one-dimensional:
for value in integers.flat:
print(value, end=' ')1 2 3 4 5 67.4 Filling Arrays with Specific Values
NumPy provides convenient functions for creating arrays filled with common values.
| Function | Purpose |
|---|---|
np.zeros() | Create an array filled with 0 |
np.ones() | Create an array filled with 1 |
np.full() | Create an array filled with a specified value |
print(np.zeros(5))
print(np.ones((2, 4), dtype=int))
print(np.full((3, 5), 13))[0. 0. 0. 0. 0.]
[[1 1 1 1]
[1 1 1 1]]
[[13 13 13 13 13]
[13 13 13 13 13]
[13 13 13 13 13]]The first argument can be an integer for one dimension or a tuple for multiple dimensions.
dtype lets you specify the element type. For example, dtype=int creates integer elements.7.5 Creating Arrays from Ranges
NumPy provides optimized functions for creating ranges of values.
Integer Ranges with arange
print(np.arange(5))
print(np.arange(5, 10))
print(np.arange(10, 1, -2))[0 1 2 3 4]
[5 6 7 8 9]
[10 8 6 4 2]The idea is similar to Python's range, but arange directly creates a NumPy array and is optimized for array use.
Floating-Point Ranges with linspace
linspace creates evenly spaced floating-point values. The ending value is included.
np.linspace(0.0, 1.0, num=5)array([0. , 0.25, 0.5 , 0.75, 1. ])Creating a Range and Reshaping It
numbers = np.arange(1, 21)
table = numbers.reshape(4, 5)
print(table)[[ 1 2 3 4 5]
[ 6 7 8 9 10]
[11 12 13 14 15]
[16 17 18 19 20]]arange → range based on a step. linspace → a specified number of evenly spaced values.7.6 List vs. Array Performance: Introducing %timeit
When you want to compare how fast two pieces of code run in IPython/Jupyter, the book uses the %timeit magic command.
%timeit [i * 2 for i in range(1000)]%timeit executes the expression repeatedly and reports timing information. The exact timing depends on your computer and environment.
The chapter compares creating millions of die rolls using a list with NumPy-based approaches. The important lesson is:
7.7 array Operators
NumPy lets arithmetic operators work on an entire array. This is called an element-wise operation.
numbers = np.arange(1, 6)
print(numbers * 2)
print(numbers ** 3)[ 2 4 6 8 10]
[ 1 8 27 64 125]Instead of writing a loop, NumPy applies the operation to every element.
Original Array Is Not Automatically Changed
numbers = np.arange(1, 6)
result = numbers * 2
print(numbers)
print(result)[1 2 3 4 5]
[ 2 4 6 8 10]But augmented assignment modifies the array:
numbers += 10
print(numbers)[11 12 13 14 15]Broadcasting
Normally, arithmetic between two arrays works when their shapes are compatible. When one operand is a scalar—a single value—NumPy can apply that value to every element. This is called broadcasting.
numbers = np.array([10, 20, 30])
print(numbers + 5)[15 25 35]NumPy can also broadcast compatible arrays of different shapes. For example, a one-dimensional array with three values can be applied to every row of a two-dimensional array with three columns.
numbers3 = np.array([[10, 20, 30],
[40, 50, 60]])
numbers4 = np.array([2, 4, 6])
print(np.multiply(numbers3, numbers4))[[ 20 80 180]
[ 80 200 360]]ValueError.7.8 NumPy Calculation Methods
Arrays provide calculation methods that can summarize their contents.
| Method | Meaning |
|---|---|
sum() | Total |
min() | Smallest value |
max() | Largest value |
mean() | Average |
std() | Standard deviation |
var() | Variance |
grades = np.array([
[87, 96, 70],
[100, 87, 90],
[94, 77, 90],
[100, 81, 82]
])
print(grades.sum())
print(grades.min())
print(grades.max())
print(grades.mean())
print(grades.std())
print(grades.var())1054
70
100
87.83333333333333
8.792357792739987
77.30555555555556Calculations by Row or Column
For a multidimensional array, the axis argument tells NumPy which dimension to use.
For example, axis=0 calculates down the rows, producing a result for each column:
grades.mean(axis=0)[95.25 85.25 83. ]7.9 Universal Functions
NumPy provides many universal functions (ufuncs). They perform operations element by element on arrays.
| Category | Examples |
|---|---|
| Math | add, subtract, multiply, divide, sqrt, log, power |
| Trigonometry | sin, cos, tan |
| Bit manipulation | bitwise_and, bitwise_or |
| Comparison | greater, less, equal, logical_and |
| Floating point | floor, ceil, isnan, fabs |
numbers = np.array([1, 4, 9, 16])
print(np.sqrt(numbers))[1. 2. 3. 4.]Universal functions fit naturally with array-oriented programming because you can operate on the whole array instead of writing a loop.
7.10 Indexing and Slicing
One-dimensional NumPy arrays use indexing and slicing syntax similar to Python sequences.
numbers = np.array([10, 20, 30, 40, 50])
print(numbers[0])
print(numbers[1:4])10
[20 30 40]Two-Dimensional Indexing
For a two-dimensional array, provide row and column indices:
numbers = np.array([
[10, 20, 30],
[40, 50, 60]
])
print(numbers[0, 1])
print(numbers[1, 2])20
60Think of it as:
Slicing a Two-Dimensional Array
print(numbers[:, 1])
print(numbers[0, :])[20 50]
[10 20 30]: means "take all values along this dimension."
numbers[row, column]. First choose the row, then choose the column.7.11 Views: Shallow Copies
A view is a shallow copy that shares the underlying data with the original array. This means changing the data through one can affect the other.
numbers = np.array([1, 2, 3, 4, 5])
numbers_view = numbers.view()
numbers[1] = 20
print(numbers)
print(numbers_view)[ 1 20 3 4 5]
[ 1 20 3 4 5]7.12 Deep Copies
When you need a completely separate array, use the array's copy() method.
numbers = np.array([1, 2, 3, 4, 5])
numbers_copy = numbers.copy()
numbers[1] = 20
print(numbers)
print(numbers_copy)[ 1 20 3 4 5]
[1 2 3 4 5]View → shares underlying data.
Copy → independent data.
The book also notes that for other Python object types, the copy module's deepcopy() can be used when a deep copy is needed.
7.13 Reshaping and Transposing
reshape()
reshape changes how the same elements are arranged into dimensions. The number of elements must remain the same.
numbers = np.arange(1, 7)
print(numbers.reshape(2, 3))[[1 2 3]
[4 5 6]]A six-element array can become 2 × 3 or 3 × 2, but it cannot become 4 × 4 because that would require 16 elements.
reshape() vs resize()
| Method | Effect |
|---|---|
reshape() | Returns a reshaped view; original shape is not changed. |
resize() | Changes the original array's shape. |
grades = np.array([[87, 96, 70],
[100, 87, 90]])
reshaped = grades.reshape(1, 6)
print(reshaped)
print(grades)Transpose
The T attribute transposes an array. For a two-dimensional array, rows become columns and columns become rows.
grades = np.array([
[87, 96, 70],
[100, 87, 90]
])
print(grades.T)[[ 87 100]
[ 96 87]
[ 70 90]]Other Shape Tools
The chapter also introduces flatten() and ravel() for producing one-dimensional representations of multidimensional arrays.
7.14 Intro to Data Science: pandas Series and DataFrames
NumPy arrays are excellent for numerical data, but real-world data can be messy. Data-science applications often need mixed data types, custom indexing, missing data and data that is not structured perfectly.
pandas provides two major array-like collections:
One-dimensional collection
Supports custom indices and missing data.
Two-dimensional table
Rows and columns with labels.
Series and DataFrames use NumPy arrays internally and can work together with many NumPy operations.
7.14.1 pandas Series
A Series is an enhanced one-dimensional array. Unlike a basic NumPy array, it can use custom indices, including strings.
Creating a Series
import pandas as pd
grades = pd.Series([87, 100, 94])
print(grades)0 87
1 100
2 94
dtype: int64By default, the indices are 0, 1, 2, ....
Creating a Series with the Same Value
pd.Series(98.6, range(3))0 98.6
1 98.6
2 98.6
dtype: float64Custom Indexing
grades = pd.Series(
[87, 100, 94],
index=['Alice', 'Bob', 'Cara']
)
print(grades)Now the labels themselves identify the values.
Series Calculations
print(grades.count())
print(grades.mean())
print(grades.min())
print(grades.max())
print(grades.std())describe() provides several descriptive statistics together.
grades.describe()7.14.2 DataFrames
A DataFrame is a two-dimensional pandas collection. Think of it as a labeled table with rows and columns.
grades = pd.DataFrame(
[[87, 96, 70],
[100, 87, 90],
[94, 77, 90],
[100, 81, 82]],
columns=['Test1', 'Test2', 'Test3'],
index=['Wally', 'Eva', 'Sam', 'Katie']
)
print(grades) Test1 Test2 Test3
Wally 87 96 70
Eva 100 87 90
Sam 94 77 90
Katie 100 81 82Selecting Data with Labels
The book demonstrates pandas selection using labels and integer positions.
print(grades.loc['Test1'])More generally:
locuses labels.ilocuses integer positions.
Boolean Indexing
Boolean indexing lets you select values that satisfy a condition.
grades[grades >= 90]Values that do not satisfy the condition appear as missing values in the resulting DataFrame.
For multiple conditions, pandas uses bitwise operators such as & and | rather than Python's and and or.
grades[(grades >= 80) & (grades < 90)]& for AND and | for OR, with each condition enclosed in parentheses.Accessing One DataFrame Cell
at uses row/column labels, while iat uses integer positions.
grades.at['Wally', 'Test1']
grades.iat[0, 0]Sorting DataFrames
The chapter demonstrates sort_index() and sort_values().
grades.sort_index(axis=1)
grades.sort_values(by='Test1', axis=1, ascending=False)By default, these sorting operations return a copy. The book also demonstrates inplace=True when you want the DataFrame itself modified rather than returning a copy.
Quick Concept Map
NumPy → numerical computing
ndarray / array → n-dimensional numerical collection
Creation → array → zeros → ones → full → arange → linspace
Attributes → ndim → shape → size → dtype → itemsize
Operations → element-wise arithmetic → broadcasting → universal functions
Calculations → sum → min → max → mean → std → var
Access → indexing → slicing
Memory → view → deep copy
Shape → reshape → resize → transpose → flatten/ravel
pandas → Series → DataFrame
List vs NumPy Array vs Series vs DataFrame
| Collection | Main strength | Typical use |
|---|---|---|
| List | General-purpose Python sequence | Everyday collections |
| NumPy array | Fast numerical array processing | Scientific computing and numerical data |
| Series | 1-D data + custom labels | Single columns/series of data |
| DataFrame | 2-D labeled table | Data analysis and tabular datasets |
Common Mistakes
- Forgetting the standard import alias:
import numpy as np. - Confusing
shapewithsize. - Trying to reshape an array into a shape with a different number of total elements.
- Assuming normal arithmetic always modifies the original array.
- Forgetting that augmented assignment such as
+=modifies the array. - Using incompatible shapes and expecting broadcasting to work.
- Confusing a view with an independent copy.
- Forgetting that two-dimensional indexing is
array[row, column]. - Using Python
and/orinstead of&/|for pandas Boolean conditions. - Thinking Series and DataFrames are unrelated to NumPy—they are closely connected to NumPy arrays.
Remember These Points
- NumPy array = ndarray.
np.array()creates an array from existing data.np.zeros(),np.ones()andnp.full()create initialized arrays.np.arange()creates integer-style ranges;np.linspace()creates evenly spaced values.ndim= dimensions;shape= arrangement;size= total elements.- NumPy arithmetic is usually element-wise.
- Broadcasting lets compatible differently shaped arrays or scalars participate in operations.
sum,min,max,mean,stdandvarsummarize array data.- View shares data; copy has independent data.
reshape()changes dimensions without changing the number of elements.Ttransposes a two-dimensional array.- Series is one-dimensional; DataFrame is two-dimensional.
locuses labels;ilocuses integer positions.
Revision Questions
- What is NumPy and what is an
ndarray? - Why can NumPy arrays be faster than Python lists for numerical processing?
- Why is
import numpy as npcommonly used? - How do you create a one-dimensional and two-dimensional array?
- What do
ndim,shape,size,dtypeanditemsizemean? - What is the difference between
arangeandlinspace? - What are
zeros,onesandfullused for? - What does
%timeitdo? - What is element-wise array arithmetic?
- What is broadcasting?
- What does the
axisargument do? - What are universal functions?
- How do you access an element of a two-dimensional array?
- What is the difference between a view and a deep copy?
- What is the difference between
reshapeandresize? - What does the
Tattribute do? - What is a pandas Series?
- What is a DataFrame?
- What is the difference between
locandiloc? - How does Boolean indexing work in pandas?
Practice Programs
Create a NumPy array containing 1–10 and display its
ndim, shape, size and dtype.Create an array of five numbers and calculate its double, square and cube without writing a loop.
Create a two-dimensional NumPy array for several students and exams. Calculate the overall mean and each exam's mean.
Create a 3×3 array and add 10 to every element using broadcasting.
Create numbers 1–20 with
arange and reshape them into a 4×5 array.Create an array, make both a view and a copy, change the original and observe which object changes.
Create a pandas Series of five student grades with student names as custom indices. Calculate
mean() and describe().Create a DataFrame containing students and three test scores. Select values using
loc, iloc, Boolean indexing and sorting.Chapter Wrap-Up
This chapter introduced NumPy's high-performance ndarray, referred to here simply as an array. You learned how to create arrays, inspect their attributes, fill them with values, create ranges, compare performance with lists, perform element-wise calculations and use broadcasting.
You also learned NumPy calculation methods, universal functions, indexing and slicing, views and deep copies, reshaping and transposing. These features make array-oriented programming concise and especially useful for numerical and data-science workloads.
The chapter then began the book's introduction to pandas. A Series provides a labeled one-dimensional collection, while a DataFrame provides a labeled two-dimensional table. These collections offer capabilities such as custom indexing, missing-data handling, selection, filtering, calculations and sorting.
Teaching note: This page is a simplified teaching edition based on the chapter organization and concepts in the supplied Python for Programmers source. Examples are rewritten for learning clarity rather than reproduced verbatim.