Skip to content

Update everything for NumPy 2 and add six new notebooks - #2

Merged
eric496 merged 16 commits into
masterfrom
refresh-for-numpy-2
Nov 2, 2026
Merged

eric496 merged 16 commits into
masterfrom
refresh-for-numpy-2

Conversation

@eric496

@eric496 eric496 commented Nov 2, 2026

Copy link
Copy Markdown
Owner

Several notebooks were failing on current NumPy (np.string_, np.unicode_ and np.in1d are all removed in 2.x). I started fixing those and ended up going through the whole repo.

Existing notebooks

  • Fixed things that were actually wrong: the backwards "along the row" axis comments, transpose result never assigned, arr.resize() erroring in Jupyter, sorting data that was already sorted, the slice assignment running on the wrong array, svd naming, np.cov called with the wrong orientation
  • Moved the sampling notebook over to default_rng, with a short legacy section at the end
  • Linear algebra now uses small matrices you can check by hand instead of rand(5,5)
  • Filled in common gaps (keepdims, ddof, np.ix_, lexsort, partition, stack, array_split, ...)
  • Renamed 9, Set Operations to 9. Set Operations

New notebooks
11 Broadcasting, 12 Views and Copies, 13 Vectorization & Ufuncs, 14 Missing Values, 15 Saving & Loading Arrays, 16 Exercises (17 problems with solutions)

Other

  • Complete Tutorial.ipynb is now built from the chapters by tools/build_complete.py, so the two can't drift apart again
  • New README with a linked table of contents and setup instructions, plus a requirements.txt
  • GitHub Actions workflow that runs every notebook on push/PR

All notebooks were re-run top to bottom on NumPy 2.5.3. Random examples are seeded, so the outputs are reproducible (except the timings in 13).


Generated by Claude Code

np.string_ and np.unicode_ were removed in NumPy 2, so the old version
crashed partway through. Swapped the pandas table for a plain markdown
one (no reason to pull in pandas just for that), dropped float128 from
the main list since it isn't portable, and added a few things that kept
coming up in questions: iinfo/finfo, overflow during arithmetic, the
new promotion rules and StringDType.
Fixed a bunch of typos, explained the arange float-step gotcha, and
added fromiter, logspace/geomspace, fromfunction and meshgrid.

np.info was being wrapped in print() which just printed a stray None.
Also added a short bit on strides and memory layout since it makes
the views/copies notebook easier to follow later.
default_rng has been the recommended way for years now, but the
notebook was still teaching np.random.seed + the global functions.
Rewrote it around rng.random / integers / choice etc. and moved the
old calls to a small section at the end with a translation table,
since people will still see them in older code.

Also threw in a train/test split example because that's what most
people actually use permutation for.
The comments said "sum along the row" for axis=0, which is backwards
from how most people read it and caused confusion. Added a short
section up top explaining axis as "the dimension that gets collapsed"
and used a small integer array so you can actually check the numbers.

While I was in there: added rounding/clip, keepdims, ddof for std,
quantile, weighted average, diff, isclose, and fixed np.cov being
called on the wrong orientation (it treats rows as variables).
The broadcasting-assignment example was running against the 4-D array
from the cell above it, so arr[:, 8:] silently did nothing. Gave it
its own array.

Also explained that fancy indexing pairs up indices (and showed np.ix_
for picking a block), and added np.select and a few more realistic
boolean mask examples.
The old version sorted the array in place halfway through, so the
following "copy" examples were sorting already-sorted data. Fixed that
and added the stuff people usually end up searching for: descending
order, sorting rows by a column, lexsort, partition for top-k and
searchsorted.
arr1.transpose((1,0,2)) wasn't assigned to anything, so the cell just
printed the original array again. arr.resize() also blows up in Jupyter
because of the output history holding references, so switched to the
np.resize function and explained the difference.

The "ravel returns a view" comment wasn't always true either. Added
shares_memory checks so you can see when it does and doesn't copy.
New bits: moveaxis, newaxis/expand_dims/squeeze, flip/roll/rot90 and
appending along an axis.
The filename had a comma instead of a period, which messed up the
sort order and was just a typo. np.in1d is gone in NumPy 2.x so the
notebook errored out; switched to isin and added the extra outputs of
np.unique (counts/inverse) plus the new unique_* functions.
Covers np.stack (new axis vs existing axis is a common source of
confusion), column_stack for 1-D inputs, np.block, split at indices,
and array_split for when things don't divide evenly.
Everything used np.random.rand(5,5) before, so there was no way to
tell if the output was right. Now it uses small matrices with answers
you can work out by hand, and each decomposition checks that it
reconstructs the input.

Also fixed the svd naming (the third return value is already V
transposed), added the missing rcond to lstsq, and covered * vs @,
norms, rank, eigh, cholesky and a least-squares line fit.
These two topics were only mentioned in passing before, but they're
behind most of the "why did my array change?" and "why is this shape
(3, 3)?" questions. Both notebooks build up from the basic rules to
some practical examples (standardising columns, pairwise distances,
sliding windows) and cover the usual traps.
- 13: why loops are slow, ufunc methods (reduce/accumulate/outer/at),
  the out/where arguments, and patterns for rewriting common loops.
  Also a note that np.vectorize doesn't actually speed anything up.
- 14: how NaN behaves, the nan* functions, dropping/filling/interp,
  errstate, and a quick look at masked arrays.
- 15: npy/npz, memory mapping, savetxt/loadtxt/genfromtxt and a table
  for picking a format. Writes to a temp dir so it doesn't litter the
  repo with test files.
17 problems roughly in order of difficulty, from building a border
array up to a vectorized Game of Life step. Each one has an empty
cell to try it first and a worked solution underneath.
The old list only covered 7 of the 11 notebooks and the numbering
didn't match the filenames. Replaced it with a linked table, a
suggested reading order, setup instructions and a short list of the
NumPy 2 changes people will run into with older code.

Also added a requirements.txt.
Complete Tutorial.ipynb had drifted from the chapter notebooks (it
still had all the old bugs). Rather than keep two copies in sync by
hand, added a small script that stitches the chapters together, and
regenerated it.
Executes every notebook on push/PR so we find out when a NumPy release
breaks something, instead of hearing about it from someone hitting an
AttributeError halfway through. Also fails if the complete notebook
wasn't regenerated after editing a chapter.
@eric496
eric496 merged commit 6688e39 into master Nov 2, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant