Written and maintained by CASRAI Editorial Board
Published · Last updated
On this page
numpy.cross(a, b) returns the cross product of two vectors, or of many vectors at once: for 3-element vectors it gives a new vector perpendicular to both inputs. Since NumPy 2.0 there are two functions for this, np.cross and np.linalg.cross. They return the same numbers for 3-element input and differ in what else they accept, which is the choice this guide helps you make.
What it is used for in research
The NumPy manual defines the cross product of a and b in R3 as “a vector perpendicular to both a and b”. In analysis code that means computing surface normals from two edge vectors, finding the axis perpendicular to a plane spanned by two measured directions, or checking whether two direction vectors are parallel (the result is the zero vector). If a and b are arrays of vectors, one call computes every cross product in the batch, with full broadcasting of the inputs.
Install or access
NumPy’s install page gives these routes. With pip: pip install numpy. With conda, inside an activated environment: conda install numpy. To keep it isolated, create a virtual environment first with python -m venv my-env, activate it (source my-env/bin/activate on macOS and Linux, my-env\Scripts\activate on Windows), then run pip install numpy. Import it with import numpy as np and check the installed version with print(np.__version__). If the import fails, NumPy maintains an ImportError troubleshooting page at https://numpy.org/doc/stable/user/troubleshooting-importerror.html.
Step-by-step: compute a cross product
- Import NumPy.
import numpy as np - Call the function on two 3-element vectors.
np.cross([1, 2, 3], [4, 5, 6])returnsarray([-3, 6, -3]). - Batch several pairs. By default the vectors lie along the last axis.
x = np.array([[1, 2, 3], [4, 5, 6]])andy = np.array([[4, 5, 6], [1, 2, 3]])givenp.cross(x, y)equal toarray([[-3, 6, -3], [ 3, -6, 3]]): one result row per input row. - Change where the vectors sit with the axis arguments. The signature is
numpy.cross(a, b, axisa=-1, axisb=-1, axisc=-1, axis=None).axisaandaxisbsay which axis ofaandbholds the vector,axiscsays which axis of the result holds it, andaxis, if given, overrides all three.
Why axisa and axisb change the answer
With the NumPy manual’s 3 by 3 example, x = [[1,2,3],[4,5,6],[7,8,9]] and y = [[7,8,9],[4,5,6],[1,2,3]], the default call treats each row as a vector and returns [[-6, 12, -6], [0, 0, 0], [6, -12, 6]]. The middle row is zero because the two middle rows are identical, so those vectors are parallel. Calling np.cross(x, y, axisa=0, axisb=0) treats each column as a vector instead and returns [[-24, 48, -24], [-30, 60, -30], [-36, 72, -36]]. Same data, different vectors, different answer; when a result looks wrong, check which axis holds your vectors first.
Output and how to read it
The function returns an ndarray. The result is perpendicular to both inputs, and its direction follows the right-hand rule. Order matters: swapping the arguments negates the result. In the examples above, np.cross([1,2,3],[4,5,6]) gives [-3, 6, -3] while np.cross([4,5,6],[1,2,3]) gives [3, -6, 3]. This is also visible in the 2 by 3 batch example, where the second row is the negative of the first because the two input rows are swapped. Parallel vectors, including a vector crossed with itself, return all zeros. To move the result’s vector axis, set axisc: with axisc=0 the 2 by 3 batch result comes back transposed, as a 3 by 2 array [[-3, 3], [6, -6], [-3, 3]]. For reshaping like that in general, see the guide to NumPy transpose.
Troubleshooting
Why does np.cross raise ValueError?
The manual states that numpy.cross raises ValueError when the dimension of the vector axis in a or b is not 3. A 4-element input fails this check. Check the shape with a.shape and make sure the length-3 axis is the one axisa, axisb or axis points at. If your vectors sit in columns, pass axisa=0, axisb=0 as shown above.
What about 2-element vectors?
The NumPy 2.0.0 release notes list under deprecations: “Arrays of 2-dimensional vectors for np.cross have been deprecated. Use arrays of 3-dimensional vectors instead.” Code that crosses 2-element vectors should be moved to 3-element vectors, for example by adding a zero third component.
Why do shapes not line up?
The function supports full broadcasting of its inputs, so a single vector can be crossed with a whole batch. Shapes that cannot broadcast raise an error. The guide to broadcasting in NumPy explains the rules, and NumPy ndarray length helps when you need to inspect dimensions.
Free alternatives
Both functions below ship with NumPy, which is free and open source.
| Function | Signature | What the manual says |
|---|---|---|
numpy.cross |
cross(a, b, axisa=-1, axisb=-1, axisc=-1, axis=None) |
Cross product of two (arrays of) vectors; vector axes default to the last axis and must have 3 dimensions. |
numpy.linalg.cross |
cross(x1, x2, /, *, axis=-1) |
Cross product of 3-element vectors; if inputs are multi-dimensional, each pair of corresponding 3-element vectors is computed independently. Array API compatible. |
np.cross vs np.linalg.cross
The 2.0.0 release notes say numpy.linalg.cross “differs from numpy.cross by accepting three-dimensional vectors only” and is compatible with the array API standard. The manual’s own example gives the same answer from both: np.linalg.cross([1,2,3],[4,5,6]) returns array([-3, 6, -3]). The practical differences are the signature (x1 and x2 are positional-only, axis is keyword-only, and there are no separate axisa, axisb, axisc) and scope. Choose np.linalg.cross when you want code that follows the array API standard and only ever handles 3-element vectors; choose np.cross when you need independent control of the input and output axes. For a column layout, np.linalg.cross(x, y, axis=0) on x = [[1,2],[3,4],[5,6]] and y = [[4,5],[6,1],[2,3]] returns [[-24, 6], [18, 24], [-6, -18]] in the manual. Related functions listed in the manual are inner and outer. For other NumPy numerical routines, see NumPy power and NumPy standard deviation.
FAQ
What does np.cross return?
An ndarray holding the cross product: a vector perpendicular to both inputs, or an array of such vectors when the inputs are arrays of vectors.
Does the order of the arguments matter?
Yes. Swapping them negates the result, as in [-3, 6, -3] versus [3, -6, 3].
Can I use np.cross on 2-D vectors?
That use was deprecated in NumPy 2.0, per the release notes quoted above. Use 3-element vectors.
Which function should I use in new code?
Both work for 3-element vectors. See the comparison above: np.linalg.cross is the 3-only, array API compatible version added in NumPy 2.0.
Sources
- NumPy manual,
numpy.cross: https://numpy.org/doc/stable/reference/generated/numpy.cross.html (checked 2026-10-29) - NumPy manual,
numpy.linalg.cross: https://numpy.org/doc/stable/reference/generated/numpy.linalg.cross.html (checked 2026-10-29) - NumPy 2.0.0 release notes: https://numpy.org/doc/stable/release/2.0.0-notes.html (checked 2026-10-29)
- NumPy installation: https://numpy.org/install/ (checked 2026-10-29)







