2. Creating Arrays
The functions below are the workhorses for constructing arrays. Master these; they appear constantly.
The functions below are the workhorses for constructing arrays. Master these; they appear constantly.
np.array() — from existing data#
Purpose: Build an ndarray from a list/tuple/nested sequence.
Syntax: np.array(object, dtype=None, copy=True, ndmin=0)
| Parameter | Meaning |
|---|---|
object |
List/tuple/array-like to convert |
dtype |
Force a data type (e.g. np.float32) |
copy |
Copy input data (default True) |
ndmin |
Minimum number of dimensions |
Return: a new ndarray.
a = np.array([1, 2, 3]) # 1-D
b = np.array([[1, 2], [3, 4]]) # 2-D
c = np.array([1, 2, 3], dtype=np.float64)
print(a, a.dtype)
print(b, b.shape)
print(c, c.dtype)
Expected Output:
[1 2 3] int64
[[1 2]
[3 4]] (2, 2)
[1. 2. 3.] float64
⚠️ Common Mistake:
np.array(1, 2, 3)fails — it expects one sequence:np.array([1, 2, 3]).
np.arange() — evenly spaced by step#
Syntax: np.arange(start, stop, step, dtype=None) — stop is exclusive.
np.arange(10) # [0 1 2 3 4 5 6 7 8 9]
np.arange(2, 10, 2) # [2 4 6 8]
np.arange(0, 1, 0.25) # [0. 0.25 0.5 0.75]
⚠️ Common Mistake: With float steps, rounding can add/drop an element unexpectedly. Prefer
linspacewhen you need an exact count.
np.linspace() — evenly spaced by count#
Syntax: np.linspace(start, stop, num=50, endpoint=True, retstep=False) — stop is inclusive by default.
np.linspace(0, 1, 5) # [0. 0.25 0.5 0.75 1. ]
np.linspace(0, 10, 5, retstep=True) # (array([ 0. , 2.5, 5. , 7.5, 10. ]), 2.5)
💡 Tip:
arangewhen you know the step;linspacewhen you know the number of points (great for plotting axes).
np.logspace() — log-scaled points#
Syntax: np.logspace(start, stop, num=50, base=10.0) → returns base**start … base**stop.
np.logspace(0, 3, 4) # [ 1. 10. 100. 1000.] (10^0 … 10^3)
zeros, ones, empty, full#
np.zeros((2, 3)) # 2x3 of 0.0
np.ones((2, 3), dtype=int) # 2x3 of 1
np.empty((2, 2)) # uninitialized garbage (fast, fill it yourself)
np.full((2, 3), 7) # 2x3 of 7
⚠️ Common Mistake:
np.emptydoes not return zeros — it returns whatever was in memory. Never read it before writing.
💡 Tip: Use
zeros_like,ones_like,full_like,empty_liketo match an existing array's shape and dtype:np.zeros_like(b) # same shape/dtype as b, filled with 0
identity, eye, diag#
np.identity(3) # 3x3 identity matrix
np.eye(3, k=1) # ones on the super-diagonal (k shifts the diagonal)
np.diag([1, 2, 3]) # build diagonal matrix from a vector
np.diag(np.array([[1,2],[3,4]])) # extract diagonal -> [1 4]
| Function | 1-D input | 2-D input |
|---|---|---|
np.diag |
builds a diagonal matrix | extracts the diagonal |
np.eye |
— | identity-like, offset diagonal via k |
fromfunction() & meshgrid()#
np.fromfunction(lambda i, j: i + j, (3, 3), dtype=int)
# [[0 1 2]
# [1 2 3]
# [2 3 4]]
x = np.array([1, 2, 3]); y = np.array([10, 20])
X, Y = np.meshgrid(x, y)
# X = [[1 2 3] Y = [[10 10 10]
# [1 2 3]] [20 20 20]]
🚀 Best Practice:
meshgridis the standard way to evaluate a functionf(x, y)over a grid for contour/surface plots and vectorized 2-D computations.
copy, astype, asarray#
a = np.array([1, 2, 3])
b = a.copy() # independent deep copy
f = a.astype(np.float64) # NEW array with a new dtype
g = np.asarray(a) # NO copy if already an ndarray of right dtype
| Function | Copies? | Use when |
|---|---|---|
.copy() |
Always | You need an independent array |
.astype() |
Always (new dtype) | Convert type |
np.asarray() |
Only if needed | Cheaply ensure "this is an ndarray" |
⭐ Interview Question: Difference between
np.arrayandnp.asarray?np.arraycopies by default (copy=True).np.asarrayavoids copying when the input is already an ndarray with the requested dtype — cheaper for pass-through code.
Real-world use case: np.linspace + meshgrid to build coordinate grids for image processing filters or plotting decision boundaries in ML.