NumPy Tutorial 02: Array Creation, Shape, and Memory Model

Download Notebook

Download this notebook

import numpy as np

1. Core constructors

Use specialized constructors when possible for clarity and performance.

a = np.array([[1, 2, 3], [4, 5, 6]], dtype=np.int32)
z = np.zeros((2, 4), dtype=np.float64)
o = np.ones((2, 4), dtype=np.float64)
r = np.arange(0, 10, 2)
l = np.linspace(0, 1, 6)

print('a:\n', a)
print('zeros shape:', z.shape)
print('ones shape:', o.shape)
print('arange:', r)
print('linspace:', l)
a:
 [[1 2 3]
 [4 5 6]]
zeros shape: (2, 4)
ones shape: (2, 4)
arange: [0 2 4 6 8]
linspace: [0.  0.2 0.4 0.6 0.8 1. ]

2. Inspecting structure

shape, ndim, size, dtype, itemsize, and nbytes are foundational attributes.

x = np.arange(24, dtype=np.int16).reshape(2, 3, 4)
print('shape:', x.shape)
print('ndim:', x.ndim)
print('size:', x.size)
print('dtype:', x.dtype)
print('itemsize:', x.itemsize)
print('nbytes:', x.nbytes)
shape: (2, 3, 4)
ndim: 3
size: 24
dtype: int16
itemsize: 2
nbytes: 48

3. Reshape and flatten family

reshape changes view/interpretation when possible; ravel prefers view; flatten always returns a copy.

x = np.arange(12)
m = x.reshape(3, 4)
rv = m.ravel()
fl = m.flatten()

m[0, 0] = 999
print('m:\n', m)
print('ravel reflects change:', rv[0])
print('flatten copy value:', fl[0])
m:
 [[999   1   2   3]
 [  4   5   6   7]
 [  8   9  10  11]]
ravel reflects change: 999
flatten copy value: 0

4. Memory order and transposition

NumPy supports C-order (row-major) and Fortran-order (column-major). Some operations create views, others create copies.

m = np.arange(12).reshape(3, 4)
t = m.T

print('Original shape:', m.shape, 'strides:', m.strides)
print('Transposed shape:', t.shape, 'strides:', t.strides)
print('Share memory?', np.shares_memory(m, t))
Original shape: (3, 4) strides: (32, 8)
Transposed shape: (4, 3) strides: (8, 32)
Share memory? True

5. Type casting strategies

Use astype to cast. Prefer controlled casting (casting='safe') in production pipelines.

x = np.array([1.2, 3.7, -2.9])
print('Original:', x, x.dtype)
xi = x.astype(np.int32)
print('Cast to int32:', xi, xi.dtype)

y = np.array([1, 2, 3], dtype=np.int64)
print('Safe cast int64 -> float64:', y.astype(np.float64, casting='safe'))
Original: [ 1.2  3.7 -2.9] float64
Cast to int32: [ 1  3 -2] int32
Safe cast int64 -> float64: [1. 2. 3.]