Skip to content
Search

NumPy

lastmod 2025-02-18created 2015-12-1772 edits

NumPy (pronounced "num-pie") is a Python library that makes it easy to work with matrices and, more generally, large multidimensional arrays. Besides data structures, NumPy provides efficiently implemented functions for numerical computation.

Categories

Examples

Libraries

NumPy APIs

  • numpy
  • numpy.reshape - Change dimensions (shape)
  • numpy.expand_dims - Add a dimension (e.g. np.expand_dims(a, axis=0))
  • numpy.newaxis - Used to add a new axis. (e.g. a[:, np.newaxis])
  • numpy.arange - Similar effect to range in python (e.g. np.arange(24))
  • numpy.astype - Used to change the dtype.
  • numpy.argwhere - Returns a list of indices of Non-zero elements. (e.g. np.argwhere(arr >= 1))

Array

1D and 2D arrays are created/used as follows.

import numpy as np

a = np.array([1, 2, 3])  # Create a rank 1 array
print type(a)            # Prints "<type 'numpy.ndarray'>"
print a.shape            # Prints "(3,)"
print a[0], a[1], a[2]   # Prints "1 2 3"

b = np.array([[1,2,3],[4,5,6]])   # Create a rank 2 array
print b.shape                     # Prints "(2, 3)"
print b[0, 0], b[0, 1], b[1, 0]   # Prints "1 2 4"

For reference, arrays can also be created in the following ways.

import numpy as np
a = np.zeros((2,2))  # Create an array of all zeros
b = np.ones((1,2))   # Create an array of all ones
c = np.full((2,2), 7) # Create a constant array
d = np.eye(2)        # Create a 2x2 identity matrix
e = np.random.random((2,2)) # Create an array filled with random values

Total number of elements:

>>> x = np.zeros((3, 5, 2), dtype=np.complex128)
>>> x.size
30
>>> np.prod(x.shape)
30

Return the indices of the elements that are non-zero:

>>> a = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
>>> a > 3
array([[False, False, False],
       [ True,  True,  True],
       [ True,  True,  True]])
>>> np.nonzero(a > 3)
(array([1, 1, 1, 2, 2, 2]), array([0, 1, 2, 0, 1, 2]))

Array slicing

Slicing can be done as follows.

import numpy as np
a = np.array([[1,2,3,4], [5,6,7,8], [9,10,11,12]])
b = a[:2, 1:3]
# [[2 3]
#  [6 7]]

row_r1 = a[1, :] # Rank 1 view of the second row of a: # Prints "[5 6 7 8] (4,)"
row_r2 = a[1:2, :] # Rank 2 view of the second row of a: # Prints "[[5 6 7 8]] (1, 4)"

col_r1 = a[:, 1] # Rank 1: [ 2,  6, 10]
col_r2 = a[:, 1:2] # Rank 2: [[ 2], [ 6], [10]]

Array Indexing

import numpy as np
a = np.array([[1,2], [3, 4], [5, 6]])
a[[0, 1, 0]] # [[1, 2], [3, 4], [1, 2]]
a[[0, 1, 0], [0, 1, 0]] # [1, 4, 1]
# a[[0, 1, 0], [0, 1]] # ERROR!

Zero-copy Buffer

That's exactly right. Zero-copy is the most common reason to use mmap. Another way to wrap a mmap with a NumPy array is to do this:

mm = mmap.mmap(...)
arr = np.ndarray(..., buffer=mm, ...)

numpy.frombuffer seems usable too

Add axis

Adding a new axis of length 1 via Indexing:

import numpy as np
a = np.array([1., 2., 3., 4.])
a[:, np.newaxis]

Adding a new axis while repeating the array:

import numpy as np
a = np.arange(8).reshape(2, 4)
b = np.tile(a, 2)

Finding max/min

>>> import numpy as np
>>> n1 = np.array([[0,0,1,2,3],
...                [5,6,7,0,0]])
>>> n1.max()
7
>>> n1.min()
0
>>> np.max(n1, axis=0)
array([5, 6, 7, 2, 3])
>>> np.max(n1, axis=1)
array([3, 7])
>>> np.min(n1, axis=0)
array([0, 0, 1, 0, 0])
>>> np.min(n1, axis=1)
array([0, 0])

min, max using the np.apply_along_axis function

Computes along the specified axis.

>>> import numpy as np
>>> n1 = np.array([[0,0,1,2,3],
...                [5,6,7,0,0]])
>>> np.apply_along_axis(lambda a: np.min(a), 1, n1)
array([0, 0])
>>> np.apply_along_axis(lambda a: np.min(a), 0, n1)
array([0, 0, 1, 0, 0])

Getting the ROI Rect of a mask

import numpy as np

def find_roi(array):
    # True 값을 가지는 좌표들을 찾습니다.
    true_indices = np.argwhere(array)

    # True 값이 없다면 ROI를 정의할 수 없습니다.
    if true_indices.size == 0:
        return None

    # 좌표들의 최소값과 최대값을 찾습니다.
    y_min, x_min = true_indices.min(axis=0)
    y_max, x_max = true_indices.max(axis=0)

    # ROI 좌표를 반환합니다. (x1, y1, x2, y2)
    return x_min, y_min, x_max, y_max

# 예시 boolean 배열
arr = np.array([[0, 0, 0, 0, 0, 0],
                [0, 0, 1, 1, 0, 0],
                [0, 0, 1, 1, 0, 0],
                [0, 0, 1, 1, 0, 0],
                [0, 0, 1, 1, 0, 0],
                [0, 0, 0, 0, 0, 0]])

roi = find_roi(arr)
print(f"ROI: {roi}")

Thoughts on the axis argument

import numpy as np
arr = np.array([[0, 0, 0, 0, 0, 0],
                [0, 0, 1, 1, 0, 0],
                [0, 0, 1, 1, 0, 0],
                [0, 0, 1, 1, 0, 0],
                [0, 0, 1, 1, 0, 0],
                [0, 0, 0, 0, 0, 0]])
idx = np.argwhere(arr)

print(idx)
"""
array([[1, 2],
       [1, 3],
       [2, 2],
       [2, 3],
       [3, 2],
       [3, 3],
       [4, 2],
       [4, 3]])
"""
  • idx.min() looks up the min value among all elements.
  • idx.min(axis=0) - axis=0 looks up the min value of each row.
  • idx.min(axis=1) - axis=1 looks up the min value of each column.

Read it like this (행 = row, 열 = column):

      행1 행2
        |  |
array([[1, 2],   - 열1
       [1, 3],   - 열2
       [2, 2],   - 열3
       [2, 3],   - 열4
       [3, 2],   - 열5
       [3, 3],   - 열6
       [4, 2],   - 열7
       [4, 3]])  - 열8
  • The result of idx.min() is 11.
  • The result of idx.min(axis=0) is array([1, 2]), since there are 2 rows.
  • The result of idx.min(axis=1) is array([1, 1, 2, 2, 2, 3, 2, 3]), since there are 8 rows.

In each case, you can see that one dimension is reduced.

Thoughts on the axis argument in 3D

import numpy as np
arr = np.array([[[1,4,3], [2,1,4]],
                [[1,4,3], [3,1,4]],
                [[4,3,2], [2,4,1]],
                [[4,3,2], [3,4,1]]])

The shape is (4, 2, 3). That is, it is an image with H=4,W=2,C=3 (RGB).

In each case, you can see that one dimension is reduced.

  • idx.min(axis=0) - axis=0 is H. With H removed it becomes W=2,C=3, and since the highest axis index is C, it finds the min value per C unit in H Steps. It finds the min value per C unit of each row.
  • idx.min(axis=1) - axis=1 is W. With W removed it becomes H=4,C=3, and since the highest axis index is C, it finds the min value per C unit in W Steps. It finds the min value per C unit of each column.
  • idx.min(axis=2) - axis=2 is C. With C removed it becomes H=4,W=2, and since the highest axis index is W, it finds the min value per W unit in H Steps. As a result, C is compressed. It becomes a GrayScale image.

The result of idx.min(axis=0):

          C1 C2 C3   C4 C5 C6
          /  /  /    /  /  /
array([[[1, 4, 3], [2, 1, 4]],
          C1 C2 C3   C4 C5 C6
          /  /  /    /  /  /
       [[1, 4, 3], [3, 1, 4]],
          C1 C2 C3   C4 C5 C6
          /  /  /    /  /  /
       [[4, 3, 2], [2, 4, 1]],
          C1 C2 C3   C4 C5 C6
          /  /  /    /  /  /
       [[4, 3, 2], [3, 4, 1]]])

Grouping the same C{N} together gives array([[1, 3, 2], [2, 1, 1]]).

The result of idx.min(axis=1) (묶음 = group):

          C1 C2 C3
          /  /  /
array([[[1, 4, 3],
        [2, 1, 4]],  ~ W1 묶음
          \  \  \
          C1 C2 C3

          C1 C2 C3
          /  /  /
       [[1, 4, 3],
        [3, 1, 4]],  ~ W2 묶음
          \  \  \
          C1 C2 C3

          C1 C2 C3
          /  /  /
       [[4, 3, 2],
        [2, 4, 1]],  ~ W3 묶음
          \  \  \
          C1 C2 C3

          C1 C2 C3
          /  /  /
       [[4, 3, 2],
        [3, 4, 1]]]) ~ W4 묶음
          \  \  \
          C1 C2 C3

Grouping C{N} together within each W{N} gives array([[1, 1, 3], [1, 1, 3], [2, 3, 1], [3, 3, 1]]).

The result of idx.min(axis=2):

array([[[1, 4, 3],   ~ W1
        [2, 1, 4]],  ~ W2
       [[1, 4, 3],   ~ W3
        [3, 1, 4]],  ~ W4
       [[4, 3, 2],   ~ W5
        [2, 4, 1]],  ~ W6
       [[4, 3, 2],   ~ W7
        [3, 4, 1]]]) ~ W8

Grouping each W{N} gives array([[1, 1], [1, 1], [2, 1], [2, 1]]).

Datatypes

import numpy as np
x = np.array([1, 2])
print x.dtype         # Prints "int64"

x = np.array([1, 2], dtype=np.int64)  # Force a particular datatype
print x.dtype # Prints "int64"

Random data

Random colors

# load the class label names
CLASSES = open(args["classes"]).read().strip().split("\n")

# if a colors file was supplied, load it from disk
if args["colors"]:
    COLORS = open(args["colors"]).read().strip().split("\n")
    COLORS = [np.array(c.split(",")).astype("int") for c in COLORS]
    COLORS = np.array(COLORS, dtype="uint8")

# otherwise, we need to randomly generate RGB colors for each class
# label
else:
    # initialize a list of colors to represent each class label in
    # the mask (starting with 'black' for the background/unlabeled
    # regions)
    np.random.seed(42)
    COLORS = np.random.randint(0, 255, size=(len(CLASSES) - 1, 3),
        dtype="uint8")
    COLORS = np.vstack([[0, 0, 0], COLORS]).astype("uint8")

RGB888 image filled with a specific color

import numpy as np

def make_rgb888(width: int, height: int, r=0, g=0, b=0) -> np.ndarray:
    return np.full(
        shape=(height, width, 3),
        fill_value=(r, g, b),
        dtype=np.int8,
    )

Valid RGB888 Image

from numpy import ndarray

DTYPE_KIND_BOOLEAN = "b"
DTYPE_KIND_SIGNED_INTEGER = "i"
DTYPE_KIND_UNSIGNED_INTEGER = "u"
DTYPE_KIND_FLOATING_POINT = "f"
DTYPE_KIND_COMPLEX_FLOATING_POINT = "c"
DTYPE_KIND_TIMEDELTA = "m"
DTYPE_KIND_DATETIME = "M"
DTYPE_KIND_OBJECT = "O"
DTYPE_KIND_BYTE_STRING = "S"
DTYPE_KIND_UNICODE = "U"
DTYPE_KIND_VOID = "V"


def valid_rgb888(image: ndarray) -> None:
    dimension = len(image.shape)
    if dimension != 3:
        raise ValueError(f"The `shape` of `image` must be 3. (vs {dimension})")

    h, w, c = image.shape
    assert h >= 1
    assert w >= 1
    assert c >= 1

    if c != 3:
        raise ValueError(f"The `channel` must be 3. (vs {c})")

    kind = image.dtype.kind
    if kind not in [DTYPE_KIND_SIGNED_INTEGER, DTYPE_KIND_UNSIGNED_INTEGER]:
        raise ValueError(
            f"The `kind` must be '{DTYPE_KIND_SIGNED_INTEGER}'"
            f" or '{DTYPE_KIND_UNSIGNED_INTEGER}'. (vs {kind})"
        )

    item_size = image.dtype.itemsize
    if item_size != 1:
        raise ValueError(f"The `item-size` must be 1. (vs {item_size})")

Creating a 1-channel mask from a 3-channel image using a color key

from typing import Final, Optional, Tuple

from numpy import concatenate, ndarray, uint8, where
from numpy.typing import NDArray

BLACK_COLOR: Final[Tuple[int, int, int]] = (0, 0, 0)
DEFAULT_CHROMA_COLOR: Final[Tuple[int, int, int]] = BLACK_COLOR
CHANNEL_MIN: Final[int] = 0
CHANNEL_MAX: Final[int] = 255

def generate_mask(
    image: NDArray[uint8],
    chroma_color=DEFAULT_CHROMA_COLOR,
) -> NDArray[uint8]:
    assert image.dtype == uint8
    assert len(image.shape) == 3
    assert image.shape[-1] == 3

    channels_cmp: NDArray[bool] = image == chroma_color
    pixel_cmp: NDArray[bool] = channels_cmp.all(axis=-1, keepdims=True)
    return where(pixel_cmp, CHANNEL_MIN, CHANNEL_MAX)

Merging a 3-channel image and a 1-channel mask into a 4-channel (BGRA) image

from typing import Final, Optional, Tuple

from numpy import concatenate, ndarray, uint8, where
from numpy.typing import NDArray

def merge_to_bgra32(image: NDArray[uint8], mask: NDArray[uint8]) -> NDArray[uint8]:
    assert image.dtype == uint8
    assert len(image.shape) == 3
    assert image.shape[-1] == 3

    assert mask.dtype == uint8
    assert len(mask.shape) == 3
    assert mask.shape[-1] == 1

    return concatenate((image, mask), axis=-1)

Boolean array indexing

import numpy as np
a = np.array([[1,2], [3, 4], [5, 6]])
bool_idx = (a > 2) # [[False, False], [ True,  True], [ True,  True]]
bool_idx.dtype # bool

Select all non-black pixels in a NumPy array

You should use np.any instead of np.all for the second case of selecting all but black pixels:

np.any(image != [0, 0, 0], axis=-1)

Or simply get a complement of black pixels by inverting a boolean array by ~:

black_pixels_mask = np.all(image == [0, 0, 0], axis=-1)
non_black_pixels_mask = ~black_pixels_mask

Working example:

import numpy as np
import matplotlib.pyplot as plt

image = plt.imread('example.png')
plt.imshow(image)
plt.show()

image_copy = image.copy()

black_pixels_mask = np.all(image == [0, 0, 0], axis=-1)

non_black_pixels_mask = np.any(image != [0, 0, 0], axis=-1)  
# or non_black_pixels_mask = ~black_pixels_mask

image_copy[black_pixels_mask] = [255, 255, 255]
image_copy[non_black_pixels_mask] = [0, 0, 0]

plt.imshow(image_copy)
plt.show()

Reversing image RGB/BGR order

Conversion between any/all of BGR, RGB, and GBR may be necessary when working with

  • Matplotlib pyplot.imshow(): M x N x 3 image, where last dimension is RGB.
  • OpenCV imshow(): M x N x 3 image, where last dimension is BGR
  • Scientific Cameras: some output M X N x 3 image, where last dimension is GBR
BGR to RGB - OpenCV image to Matplotlib
rgb = bgr[...,::-1].copy()
RGB to BGR - Matplotlib image to OpenCV
bgr = rgb[...,::-1].copy()
RGB to GBR
gbr = rgb[...,[2,0,1]].copy()

The axis order convention for Python images:

  • 3-D: W x H x 3, where the last axis is color (e.g. RGB)
  • 4-D: W x H x 3 x 1, where the last axis is typically an alpha channel

How to convert an image to Grayscale

Create a random 2x3 RGB image:

import numpy as np
width = 2
height = 3
bgr_image = np.random.randint(0, 256, (height, width, 3), dtype=np.uint8)
bgr_image

Result:

array([[[177, 140,  52],
        [ 35, 179, 111]],

       [[149, 196, 241],
        [  0,  64, 236]],

       [[188, 246,  74],
        [185, 129,  10]]], dtype=uint8)

Create a 1-channel Grayscale image using mean:

bgr_image.mean(axis=2)

Result:

array([[123.        , 108.33333333],
       [195.33333333, 100.        ],
       [169.33333333, 108.        ]])

Using np.stack, stack (bgr_image.mean(axis=2),) * 3 on the channel axis (axis=2; axis=-1 gives the same result):

np.stack((bgr_image.mean(axis=2),) * 3, axis=2).astype(dtype=np.uint8)

Result:

array([[[123, 123, 123],
        [108, 108, 108]],

       [[195, 195, 195],
        [100, 100, 100]],

       [[169, 169, 169],
        [108, 108, 108]]], dtype=uint8)

Serialize and Deserialize

import numpy as np
as_array = np.array([ [1,2,3], [4,5,6], [7,8,9] ])
array_data_type = as_array.dtype.name
array_shape = as_array.shape
as_bytes = as_array.tobytes()
result = np.frombuffer(as_bytes, dtype = array_data_type).reshape(array_shape)

stack

Joins a sequence of arrays along a new axis.

The axis parameter specifies the index of the new axis in the dimensions of the result. For example, if axis=0 it will be the first dimension and if axis=-1 it will be the last dimension:

>>> import numpy as np
>>> a = np.array([[1, 2], [3, 4]])
>>> b = np.array([[5, 6], [7, 8]])
>>> np.stack([a, b])
array([[[1, 2],
        [3, 4]],

       [[5, 6],
        [7, 8]]])

Example

import numpy as np
## ..
print x + y
print np.add(x, y)

print x - y
print np.subtract(x, y)

print x * y
print np.multiply(x, y)

print x / y
print np.divide(x, y)

print np.sqrt(x)

## 내적은 dot을 사용한다.
print v.dot(w)
print np.dot(v, w)

## 총 합은 아래와 같이 구한다.
x = np.array([[1,2],[3,4]])
print np.sum(x)  # Compute sum of all elements; prints "10"
print np.sum(x, axis=0)  # Compute sum of each column; prints "[4 6]"
print np.sum(x, axis=1)  # Compute sum of each row; prints "[3 7]"

## 랭크(Rank)를 뒤집는 방법은 아래와 같다.
x = np.array([[1,2], [3,4]])
print x.T  # Prints "[[1 3], [2 4]]"

## 동일한 크기의 배열을 만들고자 할 때.
x = np.array([[1,2,3], [4,5,6], [7,8,9], [10, 11, 12]])
y = np.empty_like(x)

## 하나의 특정 값(또는 행렬)을 사용하여 반복적으로 적용하여, 또 다른 하나의 행렬을 만든다.
v = np.array([1, 0, 1])
vv = np.tile(v, (4, 1))

Numpy generate data from linear function

You can draw random data in the form of a linear function.

Np.random.uniform_-_example.png

x = np.arange(100)
delta = np.random.uniform(-10,10, size=(100,))
y = .4 * x +3 + delta

Mean, variance, standard deviation

numpy.mean(arr) #평균
numpy.var(arr) #분산
numpy.std(arr) #표준편차

Multidimensional mean

average = img.mean(axis=0).mean(axis=0)

Reducing dimensions (flattening; flatten)

from numpy import array
a = array([[1], [2], [3]])
a.flatten()
print(a.flatten())
## Output: "[1 2 3]"

Readonly (Lock; Freeze)

import numpy as np

 a = np.zeros(11)
print("Before any change ")
print(a)

a[1] = 2
print("Before after first change ")
print(a)

a.setflags(write=False)
print("After making array immutable on attempting  second change ")
a[1] = 7

Image processing with numpy

Type Hint

from typing import TypeVar, Generic, Tuple, Union, Optional
import numpy as np

Shape = TypeVar("Shape")
DType = TypeVar("DType")


class Array(np.ndarray, Generic[Shape, DType]):
    """
    Use this to type-annotate numpy arrays, e.g.

        def transform_image(image: Array['H,W,3', np.uint8], ...):
            ...

    """
    pass


def func(arr: Array['N,2', int]):
    return arr*2


print(func(arr = np.array([(1, 2), (3, 4)])))

C Extension

Required

You must call the function below before calling any NumPy-related functions.

#include <numpy/ndarrayobject.h>
// ...
import_array();

NumPy style arrays for C++

Here are several free software that may suit your needs.

  • The GNU Scientific Library is a GPL software written in C. Thus, it has a C-like allocation and way of programming (pointers, etc.). With the GSLwrap, you can have a C++ way of programming, while still using the GSL. GSL has a BLAS implementation, but you can use ATLAS instead of the default CBLAS, if you want even more performances.
  • The boost/uBLAS library is a BSL library, written in C++ and distributed as a boost package. It is a C++-way of implementing the BLAS standard. uBLAS comes with a few linear algebra functions, and there is an experimental binding to ATLAS.
  • eigen is a linear algebra library written in C++, distributed under the LGPL3 (or GPL2). It's a C++ way of programming, but more integrated than the two others (more algorithms and data structures are available). Eigen claim to be faster than the BLAS implementations above, while not following the de-facto standard BLAS API. Eigen does not seem to put a lot of effort on parallel implementation.
  • Armadillo is LGPL3 library for C++. It has binding for LAPACK (the library used by numpy). It uses recursive templates and template meta-programming, which is a good point (I don't know if other libraries are doing it also?).
  • xtensor is a C++ library that is BSD licensed. It offers A C++ API very similar to that of NumPy. See https://xtensor.readthedocs.io/en/latest/numpy.html for a cheat sheet.

These alternatives are really good if you just want to get data structures and basic linear algebra. Depending on your taste about style, license or sysadmin challenges (installing big libraries like LAPACK may be difficult), you may choose the one that best suits your needs.

Troubleshooting

ValueError: numpy.dtype size changed, may indicate binary incompatibility. Expected 96 from C header, got 88 from PyObject

The following error occurred while using something like PandasAI:

Traceback (most recent call last):
  File "/home/yourid/Project/steel-reports/main.py", line 16, in <module>
    sys.exit(main())
  File "/home/yourid/Project/steel-reports/steelreports/entrypoint.py", line 60, in main
    return run_default_app(*files, debug=debug, verbose=verbose)
  File "/home/yourid/Project/steel-reports/steelreports/apps/__init__.py", line 7, in run_default_app
    from steelreports.apps.default import DefaultApp
  File "/home/yourid/Project/steel-reports/steelreports/apps/default.py", line 3, in <module>
    from pandasai import SmartDataframe
  File "/home/yourid/Project/steel-reports/.venv/lib/python3.9/site-packages/pandasai/__init__.py", line 6, in <module>
    from pandasai.smart_dataframe import SmartDataframe
  File "/home/yourid/Project/steel-reports/.venv/lib/python3.9/site-packages/pandasai/smart_dataframe/__init__.py", line 26, in <module>
    import pandasai.pandas as pd
  File "/home/yourid/Project/steel-reports/.venv/lib/python3.9/site-packages/pandasai/pandas/__init__.py", line 13, in <module>
    from pandas import *
  File "/home/yourid/Project/steel-reports/.venv/lib/python3.9/site-packages/pandas/__init__.py", line 22, in <module>
    from pandas.compat import is_numpy_dev as _is_numpy_dev  # pyright: ignore # noqa:F401
  File "/home/yourid/Project/steel-reports/.venv/lib/python3.9/site-packages/pandas/compat/__init__.py", line 18, in <module>
    from pandas.compat.numpy import (
  File "/home/yourid/Project/steel-reports/.venv/lib/python3.9/site-packages/pandas/compat/numpy/__init__.py", line 4, in <module>
    from pandas.util.version import Version
  File "/home/yourid/Project/steel-reports/.venv/lib/python3.9/site-packages/pandas/util/__init__.py", line 2, in <module>
    from pandas.util._decorators import (  # noqa:F401
  File "/home/yourid/Project/steel-reports/.venv/lib/python3.9/site-packages/pandas/util/_decorators.py", line 14, in <module>
    from pandas._libs.properties import cache_readonly
  File "/home/yourid/Project/steel-reports/.venv/lib/python3.9/site-packages/pandas/_libs/__init__.py", line 13, in <module>
    from pandas._libs.interval import Interval
  File "pandas/_libs/interval.pyx", line 1, in init pandas._libs.interval
ValueError: numpy.dtype size changed, may indicate binary incompatibility. Expected 96 from C header, got 88 from PyObject

It's a numpy version problem. If you're using 2.xx, downgrade to 1.xx. (As of 2024-12-03, numpy=1.26.4 is the latest)

See also

Favorite site

References


  1. Taewan.kim_-_numpy_cheat_sheet.pdf ↩

author Zer0 sitemap