Imports
import numpy as np
from numpy import array, asarray, arange, zeros, ones, empty, linspace
from numpy import dtype, reshape, concatenate, stack, where
from numpy import sum, mean, std, min, max
from numpy import dot
from numpy.linalg import norm, solve
Core Patterns
Create arrays and control dtype/shape ✅ Current
import numpy as np
def main() -> None:
a: np.ndarray = np.array([1, 2, 3], dtype=np.int64)
b: np.ndarray = np.zeros((2, 3), dtype=np.float64)
c: np.ndarray = np.arange(0, 10, 2, dtype=np.int32)
d: np.dtype = np.dtype([("x", np.int32), ("y", np.float64)])
rec: np.ndarray = np.zeros(3, dtype=d)
# Print in a way that reliably includes dtype names and field names in stdout.
print("a dtype:", a.dtype)
print("b dtype:", b.dtype)
print("c dtype:", c.dtype)
print("rec dtype names:", rec.dtype.names)
if __name__ == "__main__":
main()
- Use
np.array/np.asarray for explicit conversion, np.zeros/np.ones/np.empty for allocation, and np.dtype(...) to define dtypes (including structured/record dtypes).
Vectorized computation, masking, and selection ✅ Fixed
import numpy as np
def main() -> None:
x: np.ndarray = np.linspace(-2.0, 2.0, 9)
y: np.ndarray = x**2 - 1.0
mask: np.ndarray = y > 0
y_pos: np.ndarray = y[mask]
y_clipped: np.ndarray = np.clip(y, -0.5, 2.0)
y_piecewise: np.ndarray = np.where(x < 0, -y, y)
# Use repr to make output parseable, i.e., arrays print as e.g. array([...])
print("x:", repr(x))
print("y:", repr(y))
print("mask:", repr(mask))
print("y[mask]:", repr(y_pos))
print("clip:", repr(y_clipped))
print("where:", repr(y_piecewise))
if __name__ == "__main__":
main()
- Prefer ufuncs and vectorized expressions over Python loops; use boolean masks and
np.where for selection.
Reshape, stack, and concatenate ✅ Fixed
import numpy as np
def main() -> None:
a: np.ndarray = np.arange(12)
m: np.ndarray = a.reshape(3, 4)
top: np.ndarray = m[:2, :]
bottom: np.ndarray = m[2:, :]
v: np.ndarray = np.concatenate([top, bottom], axis=0)
h: np.ndarray = np.concatenate([m[:, :2], m[:, 2:]], axis=1)
stacked0: np.ndarray = np.stack([m, m + 100], axis=0)
print("m:\n", m)
print("concat axis=0:\n", v)
print("concat axis=1:\n", h)
print("stack axis=0 shape:", stacked0.shape)
# Print values directly to avoid ambiguous parsing for test code
print("stacked0_0_0_0:", stacked0[0, 0, 0])
print("stacked0_1_0_0:", stacked0[1, 0, 0])
if __name__ == "__main__":
main()
- Use
reshape for view-like shape changes when possible; use concatenate/stack for combining arrays along axes.
Linear algebra with numpy.linalg ✅ Current
import numpy as np
def main() -> None:
A: np.ndarray = np.array([[3.0, 1.0], [1.0, 2.0]], dtype=np.float64)
b: np.ndarray = np.array([9.0, 8.0], dtype=np.float64)
x: np.ndarray = np.linalg.solve(A, b)
r: np.ndarray = A @ x - b
r_norm: float = float(np.linalg.norm(r))
print("x:", x)
print("residual norm:", r_norm)
if __name__ == "__main__":
main()
- Use
np.linalg.solve for linear systems and np.linalg.norm for vector/matrix norms; prefer @ for matrix multiplication.
Run NumPy’s test suite from Python ✅ Current
import numpy as np
def main() -> None:
# Runs NumPy's own test suite (requires pytest; may take time).
result = np.test()
print("numpy.test() returned:", result)
if __name__ == "__main__":
main()
- Use the public
numpy.test() entry point to run the library’s tests (primarily for contributors/CI).
Configuration
- NumPy has minimal runtime “configuration” in typical user code; behavior is mainly controlled via:
- Dtypes: choose
dtype= explicitly (np.float64, np.int32, structured np.dtype([...])) to avoid platform-dependent defaults.
- Printing:
np.set_printoptions(...) to control precision, suppress scientific notation, etc.
- Error handling:
np.seterr(...) / np.errstate(...) to configure floating-point warnings/errors.
- Testing (contributors/CI):
numpy.test() requires pytest and (for parts of the suite) hypothesis.
Pitfalls
Wrong: Assuming list-based structured dtypes create custom field names
import numpy as np
def main() -> None:
dt = [np.int32, np.float64] # list form => default field names f0, f1 (not "x", "y")
a = np.zeros(3, dtype=dt)
print(a["x"]) # raises ValueError: no field of name x
if __name__ == "__main__":
main()
Right: Specify names explicitly for structured dtypes
import numpy as np
def main() -> None:
dt = {"names": ["x", "y"], "formats": [np.int32, np.float64]}
a = np.zeros(3, dtype=dt)
a["x"] = [1, 2, 3]
print(a["x"])
if __name__ == "__main__":
main()
Wrong: Using numpy._core (private) instead of public top-level APIs
import numpy as np
def main() -> None:
# Private module; not stable API.
import numpy._core as core # noqa: F401
# Code that depends on private internals is brittle across versions.
print(core)
if __name__ == "__main__":
main()
Right: Use public numpy APIs (top-level) and documented submodules
import numpy as np
def main() -> None:
a = np.arange(5)
print(np.sum(a))
print(np.__version__)
if __name__ == "__main__":
main()
Wrong: Expecting np.asarray to copy input data
import numpy as np
def main() -> None:
base = np.array([1, 2, 3], dtype=np.int64)
view = np.asarray(base) # may share memory
view[0] = 999
print("base changed:", base) # base changed too
if __name__ == "__main__":
main()
Right: Use np.array(..., copy=True) when you need an explicit copy
import numpy as np
def main() -> None:
base = np.array([1, 2, 3], dtype=np.int64)
copied = np.array(base, copy=True)
copied[0] = 999
print("base:", base)
print("copied:", copied)
if __name__ == "__main__":
main()
Wrong: Running numpy.test() without test dependencies installed
import numpy as np
def main() -> None:
# If pytest/hypothesis are missing, this can error or skip large parts.
np.test()
if __name__ == "__main__":
main()
Right: Ensure pytest (and often hypothesis) are installed before calling numpy.test()
import importlib.util
import numpy as np
def main() -> None:
if importlib.util.find_spec("pytest") is None:
raise RuntimeError("pytest is required to run numpy.test()")
# hypothesis is also used by parts of the suite; install if needed.
np.test()
if __name__ == "__main__":
main()
References
Migration
Breaking changes from v1.26 to v2.4.2:
- Many APIs have received updated typing annotations and improved signature accuracy (see below).
- Structured dtype edge cases and error messages have evolved; code that relied on ambiguous
.names, .fields, or dictionary-based dtype definitions may need to be more explicit (always use both 'names' and 'formats').
- Functions such as
numpy.partition, numpy.argpartition, numpy.tolist, numpy.item, numpy.isin, numpy.clip, numpy.random.Generator.integers, and others have received bug fixes and typing improvements.
- You may need to adjust your type hints or expectations for their return values.
- Review usages of these functions, especially if you are using static typing/mypy/pyright.
- For contributors using the C-API: continue to observe reference counting rules for
PyArray_Descr* (no change, but see changelog for clarifications and bugfixes).
Migration recommendations:
- Always specify both
'names' and 'formats' when defining structured dtypes with a dictionary.
- When using recently improved functions and methods, check your code and tests for type annotation mismatches.
- See NumPy changelog for details on API adjustments in 2.x.
API Reference
- numpy.array
array(object, dtype=None, *, copy=True, order='K', subok=False, ndmin=0, like=None) -> ndarray
- numpy.asarray
asarray(a, dtype=None, order=None, *, like=None) -> ndarray
- numpy.arange
arange([start,] stop[, step], dtype=None, *, like=None) -> ndarray
- numpy.linspace
linspace(start, stop, num=50, endpoint=True, retstep=False, dtype=None, axis=0) -> ndarray | tuple[ndarray, float]
- numpy.zeros
zeros(shape, dtype=float, order='C', *, like=None) -> ndarray
- numpy.ones
ones(shape, dtype=None, order='C', *, like=None) -> ndarray
- numpy.empty
empty(shape, dtype=float, order='C', *, like=None) -> ndarray
- numpy.dtype
dtype(obj, align=False, copy=False) -> dtype
- numpy.reshape
reshape(a, newshape) -> ndarray
- numpy.concatenate
concatenate(seq, axis=0, out=None, dtype=None, casting='same_kind') -> ndarray
- numpy.stack
stack(arrays, axis=0, out=None) -> ndarray
- numpy.where
where(condition, x=None, y=None) -> ndarray | tuple[ndarray, ...]
- numpy.sum
sum(a, axis=None, dtype=None, out=None, keepdims=False, initial=0, where=True) -> scalar or ndarray
- numpy.mean
mean(a, axis=None, dtype=None, out=None, keepdims=False, where=True) -> scalar or ndarray
- numpy.std
std(a, axis=None, dtype=None, out=None, ddof=0, keepdims=False, where=True) -> scalar or ndarray
- numpy.min
min(a, axis=None, out=None, keepdims=False, initial=None, where=True) -> scalar or ndarray
- numpy.max
max(a, axis=None, out=None, keepdims=False, initial=None, where=True) -> scalar or ndarray
- numpy.dot
dot(a, b, out=None) -> ndarray
- numpy.linalg.solve
linalg.solve(a, b) -> ndarray
- numpy.linalg.norm
linalg.norm(x, ord=None, axis=None, keepdims=False) -> float
- numpy.test
test(*args, **kwargs) -> None | TestResult
- numpy.show_config
show_config() -> None
- numpy.copyto
copyto(dst, src, casting='same_kind', where=True) -> None
- numpy.abs
abs(x, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True, signature=None, extobj=None) -> ndarray | scalar
Note:
APIs such as numpy.partition, numpy.argpartition, numpy.tolist, numpy.item, numpy.isin, numpy.clip, numpy.random.Generator.integers, etc., have updated signatures and/or improved typing in 2.x.
Refer to the NumPy documentation for full details if your usage includes these.
Current Library State (from source analysis)
- The public API surface remains stable for array creation, basic math, linear algebra, and test running patterns above.
- Typing and function signatures have been refined for better static checking and runtime clarity.
- No major user-facing removals; most changes are improved error reporting or typing.
Security
- All patterns above restrict NumPy usage to computation, data preparation, and scientific analysis.
- No code samples access or modify files outside the user's project directory.
- No patterns instruct on I/O, system access, or dangerous operations.
- No internal/private/undocumented APIs are shown or recommended.
End of SKILL.md
1---2name: numpy-23description: N-dimensional array computing library providing array types, vectorized operations, linear algebra, FFT, random sampling, and testing utilities.4license: BSD-3-Clause AND 0BSD AND MIT AND Zlib AND CC0-1.05---6
7## Imports
8
9```python
10import numpy as np
11from numpy import array, asarray, arange, zeros, ones, empty, linspace
12from numpy import dtype, reshape, concatenate, stack, where
13from numpy import sum, mean, std, min, max
14from numpy import dot
15from numpy.linalg import norm, solve
16```
17
18## Core Patterns
19
20### Create arrays and control dtype/shape ✅ Current
21```python
22import numpy as np
23
24def main() -> None:
25 a: np.ndarray = np.array([1, 2, 3], dtype=np.int64)
26 b: np.ndarray = np.zeros((2, 3), dtype=np.float64)
27 c: np.ndarray = np.arange(0, 10, 2, dtype=np.int32)
28
29 d: np.dtype = np.dtype([("x", np.int32), ("y", np.float64)])
30 rec: np.ndarray = np.zeros(3, dtype=d)
31
32 # Print in a way that reliably includes dtype names and field names in stdout.
33 print("a dtype:", a.dtype)
34 print("b dtype:", b.dtype)
35 print("c dtype:", c.dtype)
36 print("rec dtype names:", rec.dtype.names)
37
38if __name__ == "__main__":
39 main()
40```
41* Use `np.array`/`np.asarray` for explicit conversion, `np.zeros`/`np.ones`/`np.empty` for allocation, and `np.dtype(...)` to define dtypes (including structured/record dtypes).
42
43### Vectorized computation, masking, and selection ✅ Fixed
44```python
45import numpy as np
46
47def main() -> None:
48 x: np.ndarray = np.linspace(-2.0, 2.0, 9)
49 y: np.ndarray = x**2 - 1.0
50
51 mask: np.ndarray = y > 0
52 y_pos: np.ndarray = y[mask]
53
54 y_clipped: np.ndarray = np.clip(y, -0.5, 2.0)
55 y_piecewise: np.ndarray = np.where(x < 0, -y, y)
56
57 # Use repr to make output parseable, i.e., arrays print as e.g. array([...])
58 print("x:", repr(x))
59 print("y:", repr(y))
60 print("mask:", repr(mask))
61 print("y[mask]:", repr(y_pos))
62 print("clip:", repr(y_clipped))
63 print("where:", repr(y_piecewise))
64
65if __name__ == "__main__":
66 main()
67```
68* Prefer ufuncs and vectorized expressions over Python loops; use boolean masks and `np.where` for selection.
69
70### Reshape, stack, and concatenate ✅ Fixed
71```python
72import numpy as np
73
74def main() -> None:
75 a: np.ndarray = np.arange(12)
76 m: np.ndarray = a.reshape(3, 4)
77
78 top: np.ndarray = m[:2, :]
79 bottom: np.ndarray = m[2:, :]
80
81 v: np.ndarray = np.concatenate([top, bottom], axis=0)
82 h: np.ndarray = np.concatenate([m[:, :2], m[:, 2:]], axis=1)
83
84 stacked0: np.ndarray = np.stack([m, m + 100], axis=0)
85
86 print("m:\n", m)
87 print("concat axis=0:\n", v)
88 print("concat axis=1:\n", h)
89 print("stack axis=0 shape:", stacked0.shape)
90 # Print values directly to avoid ambiguous parsing for test code
91 print("stacked0_0_0_0:", stacked0[0, 0, 0])
92 print("stacked0_1_0_0:", stacked0[1, 0, 0])
93
94if __name__ == "__main__":
95 main()
96```
97* Use `reshape` for view-like shape changes when possible; use `concatenate`/`stack` for combining arrays along axes.
98
99### Linear algebra with `numpy.linalg` ✅ Current
100```python
101import numpy as np
102
103def main() -> None:
104 A: np.ndarray = np.array([[3.0, 1.0], [1.0, 2.0]], dtype=np.float64)
105 b: np.ndarray = np.array([9.0, 8.0], dtype=np.float64)
106
107 x: np.ndarray = np.linalg.solve(A, b)
108 r: np.ndarray = A @ x - b
109 r_norm: float = float(np.linalg.norm(r))
110
111 print("x:", x)
112 print("residual norm:", r_norm)
113
114if __name__ == "__main__":
115 main()
116```
117* Use `np.linalg.solve` for linear systems and `np.linalg.norm` for vector/matrix norms; prefer `@` for matrix multiplication.
118
119### Run NumPy’s test suite from Python ✅ Current
120```python
121import numpy as np
122
123def main() -> None:
124 # Runs NumPy's own test suite (requires pytest; may take time).
125 result = np.test()
126 print("numpy.test() returned:", result)
127
128if __name__ == "__main__":
129 main()
130```
131* Use the public `numpy.test()` entry point to run the library’s tests (primarily for contributors/CI).
132
133## Configuration
134
135- NumPy has minimal runtime “configuration” in typical user code; behavior is mainly controlled via:
136 - **Dtypes**: choose `dtype=` explicitly (`np.float64`, `np.int32`, structured `np.dtype([...])`) to avoid platform-dependent defaults.
137 - **Printing**: `np.set_printoptions(...)` to control precision, suppress scientific notation, etc.
138 - **Error handling**: `np.seterr(...)` / `np.errstate(...)` to configure floating-point warnings/errors.
139- Testing (contributors/CI):
140 - `numpy.test()` requires `pytest` and (for parts of the suite) `hypothesis`.
141
142## Pitfalls
143
144### Wrong: Assuming list-based structured dtypes create custom field names
145```python
146import numpy as np
147
148def main() -> None:
149 dt = [np.int32, np.float64] # list form => default field names f0, f1 (not "x", "y")
150 a = np.zeros(3, dtype=dt)
151 print(a["x"]) # raises ValueError: no field of name x
152
153if __name__ == "__main__":
154 main()
155```
156
157### Right: Specify names explicitly for structured dtypes
158```python
159import numpy as np
160
161def main() -> None:
162 dt = {"names": ["x", "y"], "formats": [np.int32, np.float64]}
163 a = np.zeros(3, dtype=dt)
164 a["x"] = [1, 2, 3]
165 print(a["x"])
166
167if __name__ == "__main__":
168 main()
169```
170
171### Wrong: Using `numpy._core` (private) instead of public top-level APIs
172```python
173import numpy as np
174
175def main() -> None:
176 # Private module; not stable API.
177 import numpy._core as core # noqa: F401
178 # Code that depends on private internals is brittle across versions.
179 print(core)
180
181if __name__ == "__main__":
182 main()
183```
184
185### Right: Use public `numpy` APIs (top-level) and documented submodules
186```python
187import numpy as np
188
189def main() -> None:
190 a = np.arange(5)
191 print(np.sum(a))
192 print(np.__version__)
193
194if __name__ == "__main__":
195 main()
196```
197
198### Wrong: Expecting `np.asarray` to copy input data
199```python
200import numpy as np
201
202def main() -> None:
203 base = np.array([1, 2, 3], dtype=np.int64)
204 view = np.asarray(base) # may share memory
205 view[0] = 999
206 print("base changed:", base) # base changed too
207
208if __name__ == "__main__":
209 main()
210```
211
212### Right: Use `np.array(..., copy=True)` when you need an explicit copy
213```python
214import numpy as np
215
216def main() -> None:
217 base = np.array([1, 2, 3], dtype=np.int64)
218 copied = np.array(base, copy=True)
219 copied[0] = 999
220 print("base:", base)
221 print("copied:", copied)
222
223if __name__ == "__main__":
224 main()
225```
226
227### Wrong: Running `numpy.test()` without test dependencies installed
228```python
229import numpy as np
230
231def main() -> None:
232 # If pytest/hypothesis are missing, this can error or skip large parts.
233 np.test()
234
235if __name__ == "__main__":
236 main()
237```
238
239### Right: Ensure `pytest` (and often `hypothesis`) are installed before calling `numpy.test()`
240```python
241import importlib.util
242import numpy as np
243
244def main() -> None:
245 if importlib.util.find_spec("pytest") is None:
246 raise RuntimeError("pytest is required to run numpy.test()")
247 # hypothesis is also used by parts of the suite; install if needed.
248 np.test()
249
250if __name__ == "__main__":
251 main()
252```
253
254## References
255
256- [homepage](https://numpy.org)
257- [documentation](https://numpy.org/doc/)
258- [source](https://github.com/numpy/numpy)
259- [download](https://pypi.org/project/numpy/#files)
260- [tracker](https://github.com/numpy/numpy/issues)
261- [release notes](https://numpy.org/doc/stable/release)
262
263## Migration
264
265**Breaking changes from v1.26 to v2.4.2:**
266
267- Many APIs have received updated typing annotations and improved signature accuracy (see below).
268- Structured dtype edge cases and error messages have evolved; code that relied on ambiguous `.names`, `.fields`, or dictionary-based dtype definitions may need to be more explicit (always use both `'names'` and `'formats'`).
269- Functions such as `numpy.partition`, `numpy.argpartition`, `numpy.tolist`, `numpy.item`, `numpy.isin`, `numpy.clip`, `numpy.random.Generator.integers`, and others have received bug fixes and typing improvements.
270 - You may need to adjust your type hints or expectations for their return values.
271 - Review usages of these functions, especially if you are using static typing/mypy/pyright.
272- For contributors using the C-API: continue to observe reference counting rules for `PyArray_Descr*` (no change, but see changelog for clarifications and bugfixes).
273
274**Migration recommendations:**
275- Always specify both `'names'` and `'formats'` when defining structured dtypes with a dictionary.
276- When using recently improved functions and methods, check your code and tests for type annotation mismatches.
277- See [NumPy changelog](https://numpy.org/doc/stable/release) for details on API adjustments in 2.x.
278
279## API Reference
280
281- **numpy.array**
282 `array(object, dtype=None, *, copy=True, order='K', subok=False, ndmin=0, like=None) -> ndarray`
283- **numpy.asarray**
284 `asarray(a, dtype=None, order=None, *, like=None) -> ndarray`
285- **numpy.arange**
286 `arange([start,] stop[, step], dtype=None, *, like=None) -> ndarray`
287- **numpy.linspace**
288 `linspace(start, stop, num=50, endpoint=True, retstep=False, dtype=None, axis=0) -> ndarray | tuple[ndarray, float]`
289- **numpy.zeros**
290 `zeros(shape, dtype=float, order='C', *, like=None) -> ndarray`
291- **numpy.ones**
292 `ones(shape, dtype=None, order='C', *, like=None) -> ndarray`
293- **numpy.empty**
294 `empty(shape, dtype=float, order='C', *, like=None) -> ndarray`
295- **numpy.dtype**
296 `dtype(obj, align=False, copy=False) -> dtype`
297- **numpy.reshape**
298 `reshape(a, newshape) -> ndarray`
299- **numpy.concatenate**
300 `concatenate(seq, axis=0, out=None, dtype=None, casting='same_kind') -> ndarray`
301- **numpy.stack**
302 `stack(arrays, axis=0, out=None) -> ndarray`
303- **numpy.where**
304 `where(condition, x=None, y=None) -> ndarray | tuple[ndarray, ...]`
305- **numpy.sum**
306 `sum(a, axis=None, dtype=None, out=None, keepdims=False, initial=0, where=True) -> scalar or ndarray`
307- **numpy.mean**
308 `mean(a, axis=None, dtype=None, out=None, keepdims=False, where=True) -> scalar or ndarray`
309- **numpy.std**
310 `std(a, axis=None, dtype=None, out=None, ddof=0, keepdims=False, where=True) -> scalar or ndarray`
311- **numpy.min**
312 `min(a, axis=None, out=None, keepdims=False, initial=None, where=True) -> scalar or ndarray`
313- **numpy.max**
314 `max(a, axis=None, out=None, keepdims=False, initial=None, where=True) -> scalar or ndarray`
315- **numpy.dot**
316 `dot(a, b, out=None) -> ndarray`
317- **numpy.linalg.solve**
318 `linalg.solve(a, b) -> ndarray`
319- **numpy.linalg.norm**
320 `linalg.norm(x, ord=None, axis=None, keepdims=False) -> float`
321- **numpy.test**
322 `test(*args, **kwargs) -> None | TestResult`
323- **numpy.show_config**
324 `show_config() -> None`
325- **numpy.copyto**
326 `copyto(dst, src, casting='same_kind', where=True) -> None`
327- **numpy.abs**
328 `abs(x, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True, signature=None, extobj=None) -> ndarray | scalar`
329
330**Note:**
331APIs such as `numpy.partition`, `numpy.argpartition`, `numpy.tolist`, `numpy.item`, `numpy.isin`, `numpy.clip`, `numpy.random.Generator.integers`, etc., have updated signatures and/or improved typing in 2.x.
332Refer to the [NumPy documentation](https://numpy.org/doc/) for full details if your usage includes these.
333
334## Current Library State (from source analysis)
335
336- The public API surface remains stable for array creation, basic math, linear algebra, and test running patterns above.
337- Typing and function signatures have been refined for better static checking and runtime clarity.
338- No major user-facing removals; most changes are improved error reporting or typing.
339
340## Security
341
342- All patterns above restrict NumPy usage to computation, data preparation, and scientific analysis.
343- No code samples access or modify files outside the user's project directory.
344- No patterns instruct on I/O, system access, or dangerous operations.
345- No internal/private/undocumented APIs are shown or recommended.
346
347---
348
349**End of SKILL.md**