Installation and Importing
NumPy is a single package that installs cleanly on every platform, and the import convention is part of the language: it is always imported as np. The chapter also covers the ten-second smoke test that confirms the install, the version-pairing rules that keep the rest of the stack consistent, and the one import mistake worth knowing (shadows and partial imports).
Install
pip install numpy
# verify
python -c "import numpy; print(numpy.__version__)"
Current releases ship prebuilt wheels for Windows, macOS (including Apple Silicon), and Linux, so no compiler is needed. If a build-from-source is ever required, a C compiler and a BLAS/LAPACK library are the dependencies - but for application work the wheels are the entire story.
The Import Convention
import numpy as np
a = np.array([1, 2, 3])
print(a + 10) # [11 12 13] - the engine works
print(np.__version__)
import numpy as np is universal in the ecosystem - tutorials, libraries, and production code all use it, and the np. prefix makes the source of every call visible. Two anti-patterns to avoid:
- Wildcard imports (
from numpy import *) - they flood the namespace and make it impossible to tell whichmeanis in play. Import specific names only in small scripts where the collision risk is visible:from numpy import array, zeros. - Shadows. A local file named
numpy.pyanywhere on the path silently replaces the package. Ifimport numpystarts behaving strangely, checknumpy.__file__first - it should point inside site-packages, not your project directory.
The Submodules That Matter
import numpy as np
# most of the API is top-level; a few namespaces are explicit
rng = np.random.default_rng(0) # the modern random generator
print(np.linalg.norm([3, 4])) # linear algebra
print(np.fft.fft([1, 0, -1, 0])) # fourier transforms
print(np.polynomial.polynomial.poly1d) # polynomial tools
The top-level namespace holds arrays, creation functions, ufuncs, and aggregation - the daily 90%. np.linalg, np.random, np.fft, and np.polynomial are the submodules you reach for explicitly. There is no need to import submodules separately; the np. prefix reaches them all.
Version Pairing
# record the exact version in the project
python -c "import numpy; print(numpy.__version__)" > numpy_version.txt
# or pin in requirements
pip freeze | grep -i numpy
- Pin NumPy in the requirements file - it is the one package where a minor version jump can change behavior (dtype promotion rules, deprecations) across a whole stack.
- Other scientific packages declare compatible NumPy ranges; when pip resolves a conflict, let it choose a version that satisfies all dependents rather than forcing your own.
- Check
np.show_config()once in a new environment - it prints the BLAS/LAPACK backend, which is what your linear-algebra performance actually depends on.
The Smoke Test
import numpy as np
a = np.arange(6).reshape(2, 3)
assert a.shape == (2, 3)
assert (a + 1).sum() == a.sum() + 6
assert np.dot(a, a.T).shape == (2, 2)
print("numpy ok:", np.__version__)
Three lines that exercise array creation, shape, a ufunc, and a linear-algebra call. Run it once per environment - it catches a shadowed module, a broken wheel, or a mismatched build in five seconds, instead of discovering the problem inside the first real computation.
Summary
Install with pip (wheels cover every platform), import as np - the universal convention - and keep the namespace clean: no wildcard imports, no local numpy.py. Pin the version in requirements, check np.show_config() to see the BLAS backend, and run the three-line smoke test in each new environment. Ten seconds of setup discipline is the difference between a working stack and a debugging session about imports.