# NumPy

**NumPy** is the primary open-source [array programming](https://www.edgepedia.org/array-programming) library for the [Python](https://www.edgepedia.org/python-programming-language) language, providing a multidimensional array object and fast routines for mathematical, logical, linear algebra, [Fourier transform](https://www.edgepedia.org/fourier-transform), and random simulation operations on arrays<sup>[1](https://numpy.org/doc/stable/index.html?highlight=mathematical+functions)</sup>. In the Python world, NumPy arrays are the standard representation for numerical data<sup>[2](https://arxiv.org/abs/1102.1523)</sup>, and the library is the foundation upon which the scientific Python ecosystem is constructed, with roles in research pipelines spanning physics, chemistry, astronomy, biology, engineering, finance, and economics<sup>[3](https://arxiv.org/abs/2006.10256)</sup>.

| Key fact | Detail |
|---|---|
| What it provides | A multidimensional, homogeneously typed, strided in-RAM array object (the `ndarray`) plus routines for fast operations on arrays<sup>[1](https://numpy.org/doc/stable/index.html?highlight=mathematical+functions)</sup><sup> • </sup><sup>[4](https://doi.org/10.1038/s41586-020-2649-2)</sup> |
| First release under the NumPy name | NumPy 0.9.2, January 2006, successor to both Numeric and Numarray, announced by Travis Oliphant<sup>[5](https://mail.python.org/pipermail/numpy-discussion/2006-January/005548.html)</sup> |
| Major release | NumPy 2.0.0, 16 June 2024, the first major release since 2006, by 212 contributors over 1078 pull requests, including an ABI break<sup>[6](https://numpy.org/news/)</sup> |
| Core mechanism | Universal functions (ufuncs) operate element-by-element with broadcasting and type casting; looping occurs in compiled C rather than Python<sup>[7](https://numpy.org/doc/stable/user/basics.ufuncs.html)</sup><sup> • </sup><sup>[8](https://numpy.org/doc/stable/user/basics.broadcasting)</sup> |
| Linear algebra backend | BLAS and LAPACK, with optimized implementations such as OpenBLAS, MKL, and ATLAS preferred when available<sup>[9](https://numpy.org/doc/stable/reference/routines.linalg.html)</sup> |
| Hardware scope | CPU-only; GPU and distributed arrays are handled through interoperability protocols such as DLPack and `__array_ufunc__`<sup>[10](https://numpy.org/neps/nep-0047-array-api-standard.html)</sup> |
| Governance | Community-owned project affiliated with the 501(c)3 NumFOCUS Foundation, released under a BSD-style license<sup>[11](https://numpy.org/devdocs/dev/governance/governance.html)</sup> |
| Landmark publication | Harris et al., "Array programming with NumPy," *Nature* 585, 357–362 (2020)<sup>[4](https://doi.org/10.1038/s41586-020-2649-2)</sup> |

## The array structure

A NumPy array is a data structure of two parts: a data buffer holding the actual elements, and metadata describing the data type, shape, and strides, which are the byte offsets used to move between consecutive elements along each dimension<sup>[12](https://numpy.org/doc/stable/user/basics.copies.html?highlight=indexing)</sup>. Because the metadata is separate from the buffer, the same memory can be reinterpreted with a different shape, offset, byte order, or dtype without moving any bytes<sup>[13](https://numpy.org/doc/1.21/reference/internals.html)</sup>.

**Views and copies.** Operations that only change metadata produce views, which share the underlying data buffer, so a change made through a view appears in the original array. Basic indexing, such as slicing, always creates a view. Operations that duplicate both buffer and metadata produce copies, and advanced indexing with arrays of indices always creates a copy<sup>[12](https://numpy.org/doc/stable/user/basics.copies.html?highlight=indexing)</sup>. The `base` attribute distinguishes the two cases: it returns the original array for a view and `None` for a copy<sup>[12](https://numpy.org/doc/stable/user/basics.copies.html?highlight=indexing)</sup>. Avoiding needless data copying is one of the three techniques, alongside vectorization and minimizing operation counts, that make numerical computation efficient in a high-level language<sup>[2](https://arxiv.org/abs/1102.1523)</sup>.

## Universal functions and broadcasting

A universal function, or ufunc, is a function that operates on `ndarray` objects element by element, supporting array broadcasting, type casting, and other standard features; it is a vectorized wrapper for a function taking a fixed number of inputs and producing a fixed number of outputs<sup>[7](https://numpy.org/doc/stable/user/basics.ufuncs.html)</sup>. Many built-in ufuncs are implemented in compiled C code<sup>[7](https://numpy.org/doc/stable/user/basics.ufuncs.html)</sup>. Generalized ufuncs (gufuncs) operate on sub-arrays such as vectors and matrices instead of single scalars; `numpy.add` is an element-wise ufunc, while `numpy.matmul`, which implements the `@` matrix multiplication operator introduced in NumPy 1.10.0, is a gufunc<sup>[7](https://numpy.org/doc/stable/user/basics.ufuncs.html)</sup><sup> • </sup><sup>[9](https://numpy.org/doc/stable/reference/routines.linalg.html)</sup>.

All ufuncs have five methods: the four reduce-like methods `reduce`, `accumulate`, `reduceat`, and `outer`, and `at` for in-place operations using advanced indexing<sup>[7](https://numpy.org/doc/stable/user/basics.ufuncs.html)</sup>. Classes, including ndarray subclasses, can override how ufuncs act on them by defining special methods such as `__array_ufunc__`<sup>[7](https://numpy.org/doc/stable/user/basics.ufuncs.html)</sup>.

**Broadcasting** describes how NumPy treats arrays with different shapes during arithmetic: subject to constraints, the smaller array is broadcast across the larger one so their shapes become compatible. This vectorizes operations so looping occurs in C instead of Python, without making needless copies of data, though cases exist where broadcasting leads to inefficient memory use<sup>[8](https://numpy.org/doc/stable/user/basics.broadcasting)</sup>. Under the broadcasting rules, an input with a dimension of size 1 reuses its first data entry along that dimension, implemented by giving that dimension a stride of 0<sup>[7](https://numpy.org/doc/stable/user/basics.ufuncs.html)</sup>.

## Linear algebra and compiled backends

The `numpy.linalg` functions rely on BLAS and LAPACK for efficient low-level implementations of standard linear algebra algorithms. NumPy can supply C versions of a subset of the reference implementations itself, but when possible it uses highly optimized, multithreaded libraries that exploit specialized processor functionality, such as OpenBLAS, MKL, and ATLAS; environment variables and packages like threadpoolctl may be needed to control thread counts<sup>[9](https://numpy.org/doc/stable/reference/routines.linalg.html)</sup>.

The SciPy library has an overlapping `linalg` submodule with functions NumPy lacks, such as LU and Schur decompositions, additional pseudoinverse methods, and matrix transcendentals like the [matrix logarithm](https://www.edgepedia.org/matrix-logarithm). Some NumPy functions have more flexible broadcasting: `numpy.linalg.solve` handles stacked arrays, while `scipy.linalg.solve` accepts only a single square array as its first argument<sup>[9](https://numpy.org/doc/stable/reference/routines.linalg.html)</sup>. The documentation treats "matrix" as a 2-D `numpy.array`; the `numpy.matrix` object is no longer recommended, even for linear algebra<sup>[9](https://numpy.org/doc/stable/reference/routines.linalg.html)</sup>.

## History

NumPy descends from two earlier Python array packages, Numeric and Numarray, both of which are no longer maintained<sup>[14](https://numpy.org/history/)</sup>. In the mid-1990s an international team of volunteers began developing a data structure for efficient array computation, which evolved into the N-dimensional NumPy array<sup>[2](https://arxiv.org/abs/1102.1523)</sup>. NumPy 0.9.2, announced by Travis Oliphant on 5 January 2006, was the first release under the new name and was built from code of both predecessors, bringing in Numarray's faster sorting functions for a factor of 2 to 3 speed increase in sorting<sup>[5](https://mail.python.org/pipermail/numpy-discussion/2006-January/005548.html)</sup>.

The project's own history page records that it began with little funding, written mainly by graduate students, many without computer science education<sup>[14](https://numpy.org/history/)</sup>. NumPy 1.22.0 (31 December 2021) added a DLPack backend, a preliminary version of the array API standard (NEP 47), and essentially complete type annotations of the main namespace, with 153 contributors over 609 pull requests<sup>[6](https://numpy.org/news/)</sup>. NumPy 2.0.0 followed on 16 June 2024 as the first major release since 2006, containing breaking changes that could not happen in a minor release, including an ABI break, changes to type promotion rules, and API changes<sup>[6](https://numpy.org/news/)</sup>. NumPy 2.1.0 added experimental support for free-threaded [CPython](https://www.edgepedia.org/cpython) 3.13, in which the global interpreter lock is disabled<sup>[15](https://numpy.org/doc/stable/reference/thread_safety.html)</sup>, and NumPy 2.5.0 (21 June 2026) dropped Python 3.11 support and added descending sorts compliant with the array API standard<sup>[6](https://numpy.org/news/)</sup>.

## Ecosystem role and interoperability

NumPy is so pervasive that several projects targeting specialized audiences have developed their own NumPy-like interfaces and array objects, and NumPy increasingly serves as an interoperability layer between these libraries<sup>[3](https://arxiv.org/abs/2006.10256)</sup>. NumPy itself is CPU-only, providing in-memory, multidimensional, homogeneously typed arrays on CPUs<sup>[4](https://doi.org/10.1038/s41586-020-2649-2)</sup>. GPU arrays (CuPy), sparse arrays, parallel arrays (Dask), and NumPy-like implementations in [TensorFlow](https://www.edgepedia.org/tensorflow) and PyTorch reimplement the NumPy API for their own storage strategies<sup>[16](https://numpy.org/doc/1.26/user/basics.interoperability.html)</sup>.

Several protocols make this work in practice. The `__array_ufunc__` and `__array_function__` protocols let foreign objects defer execution of NumPy operations to their own implementations; CuPy arrays, for example, implement `__array_ufunc__` so that `np.exp` on a CuPy array runs the matching CUDA or ROCm code and returns a CuPy array<sup>[17](https://numpy.org/doc/stable/user/basics.interoperability.html?highlight=cuda)</sup>. DLPack defines a memory layout for strided n-dimensional arrays and is the only major exchange protocol with device support, allowing GPU-to-GPU exchange between libraries such as PyTorch and CuPy; NumPy's `np.from_dlpack` imports CPU data as a read-only view<sup>[10](https://numpy.org/neps/nep-0047-array-api-standard.html)</sup><sup> • </sup><sup>[17](https://numpy.org/doc/stable/user/basics.interoperability.html?highlight=cuda)</sup>. In NumPy 2.0 the project adopted the array API standard (version 2022.12) in its main namespace under NEP 56, giving libraries such as CuPy, JAX, and PyTorch a more well-defined, minimal API surface to target<sup>[18](https://numpy.org/neps/roadmap.html)</sup>.

NumPy's influence extends to celebrated scientific work: the scripts released for analyzing gravitational waves rely on NumPy imports, and the effort to image the M87 black hole gives it a direct citation<sup>[14](https://numpy.org/history/)</sup>. Downloads from PyPI exceeded 200 million per month as of May 2024<sup>[18](https://numpy.org/neps/roadmap.html)</sup>.

## Governance and community

The NumPy Project is an open-source software project affiliated with the 501(c)3 NumFOCUS Foundation, which serves as its fiscal sponsor and is the only legal entity with a formal relationship to the project. The software is released under a BSD or similar license and hosted in public GitHub repositories under the `numpy` organization<sup>[11](https://numpy.org/devdocs/dev/governance/governance.html)</sup>. Decisions about project direction are made by community consensus, with a steering council responsible for facilitating consensus, stewarding resources, and making decisions if the normal community process breaks down<sup>[11](https://numpy.org/devdocs/dev/governance/governance.html)</sup>. Development priorities are recorded in a public roadmap and through NumPy Enhancement Proposals (NEPs)<sup>[19](https://numpy.org/neps/index.html)</sup>.

## Performance practice

Three techniques underpin efficient numerical computation with NumPy: vectorizing calculations, avoiding copying data in memory, and minimizing operation counts<sup>[2](https://arxiv.org/abs/1102.1523)</sup>. Many NumPy operations release the Python global interpreter lock (GIL), so multithreaded Python code can gain parallel performance when each worker thread owns its own arrays; sharing arrays between mutating threads risks inconsistent, race-prone results, and operations on `dtype=np.object_` arrays do not release the GIL<sup>[15](https://numpy.org/doc/stable/reference/thread_safety.html)</sup>. Ongoing performance work centers on Universal SIMD intrinsics that provide improvements across hardware platforms through an abstraction layer, a transition from C to C++ in the internals, and adoption of Google Highway for the SIMD infrastructure<sup>[18](https://numpy.org/neps/roadmap.html)</sup>.

## References

1. [NumPy documentation, NumPy v2.3 Manual](https://numpy.org/doc/stable/index.html?highlight=mathematical+functions)
2. [Stéfan van der Walt, S. Chris Colbert, Gaël Varoquaux (2011). The NumPy array: a structure for efficient numerical computation. arXiv:1102.1523](https://arxiv.org/abs/1102.1523)
3. [Charles R. Harris et al. (2020). Array Programming with NumPy. arXiv:2006.10256](https://arxiv.org/abs/2006.10256)
4. [Harris, C.R., Millman, K.J., van der Walt, S.J. et al. Array programming with NumPy. Nature 585, 357–362 (2020)](https://doi.org/10.1038/s41586-020-2649-2)
5. [Travis Oliphant (5 January 2006). ANN: Release of NumPy 0.9.2, numpy-discussion mailing list](https://mail.python.org/pipermail/numpy-discussion/2006-January/005548.html)
6. [NumPy News, numpy.org](https://numpy.org/news/)
7. [Universal functions (ufunc) basics, NumPy v2.5 Manual](https://numpy.org/doc/stable/user/basics.ufuncs.html)
8. [Broadcasting, NumPy v2.5 Manual](https://numpy.org/doc/stable/user/basics.broadcasting)
9. [Linear algebra, NumPy v2.5 Manual](https://numpy.org/doc/stable/reference/routines.linalg.html)
10. [NEP 47 — Adopting the array API standard](https://numpy.org/neps/nep-0047-array-api-standard.html)
11. [NumPy project governance and decision-making, NumPy devdocs](https://numpy.org/devdocs/dev/governance/governance.html)
12. [Copies and views, NumPy v2.5 Manual](https://numpy.org/doc/stable/user/basics.copies.html?highlight=indexing)
13. [NumPy internals, NumPy v1.21 Manual](https://numpy.org/doc/1.21/reference/internals.html)
14. [History of NumPy, numpy.org](https://numpy.org/history/)
15. [Thread Safety, NumPy v2.5 Manual](https://numpy.org/doc/stable/reference/thread_safety.html)
16. [Interoperability with NumPy, NumPy v1.26 Manual](https://numpy.org/doc/1.26/user/basics.interoperability.html)
17. [Interoperability with NumPy, NumPy v2.5 Manual](https://numpy.org/doc/stable/user/basics.interoperability.html?highlight=cuda)
18. [NumPy roadmap, NumPy Enhancement Proposals](https://numpy.org/neps/roadmap.html)
19. [Roadmap & NumPy enhancement proposals, numpy.org/neps](https://numpy.org/neps/index.html)

---
*Topic: Encyclopedia › Physical world and mathematics › Mathematics and statistics › Numbers and algebra › Linear and multilinear algebra › Numerical linear algebra › Numerical linear algebra software*

*Initially written Sep 17, 2026 · Reviewed: Sep 30, 2026; Oct 15, 2026 · Edited: Sep 30, 2026; Oct 15, 2026 · Last review: Oct 15, 2026*

*Copyright 2026 EdgeChat AI, a subsidiary of Biostate AI.*

License: Edgepedia Community License 1.0, https://www.edgepedia.org/edgepedia/license
