Universal Functions (ufuncs)
Use NumPy's fast element-wise maths functions — sqrt, exp, log, abs, round/floor/ceil, power, mod, maximum, sin/cos — on whole arrays.
Operators like + and * cover basic maths. For square roots, logarithms, rounding or "the bigger of two scores", NumPy gives you a large family of functions that work on every element at once. They are called universal functions, or ufuncs. In fact, every operator you used in the previous topic secretly calls a ufunc (a + b is np.add(a, b)).
Definition
A universal function (ufunc) is a NumPy function that operates element by element on arrays, written in compiled C for speed. It takes one array (a unary ufunc, e.g.
np.sqrt) or two arrays (a binary ufunc, e.g.np.power), and returns a new array of the same shape — supporting broadcasting, type conversion and an optionalout=argument.
- Element by element —
np.sqrt(arr)takes the square root of each element separately. - Unary vs binary — unary ufuncs need one input (
np.abs(a)); binary ones need two (np.maximum(a, b),np.power(a, 2)). - Same shape — a
(3, 6)input gives a(3, 6)output. - Not the
mathmodule —math.sqrtworks on one number only;np.sqrtworks on whole arrays.
Syntax
python
np.ufunc_name(x) # unary
np.ufunc_name(x1, x2) # binary
np.ufunc_name(x, out=result) # write into an existing array
np.round(x, decimals=0) # round (also: arr.round(1))| Parameter | Meaning | Default |
|---|---|---|
x / x1, x2 | input array(s) or scalars | — (required) |
out | existing array to store the result in (saves memory) | None (new array) |
where | boolean mask: compute only where True | True (everywhere) |
decimals (np.round only) | number of decimal places | 0 |
The ufunc table
| Function | What it does | Example input → output |
|---|---|---|
np.sqrt(x) | square root | [4, 9, 16] → [2. 3. 4.] |
np.square(x) | x² | [2, 3] → [4 9] |
np.exp(x) | eˣ (e ≈ 2.718) | [0, 1] → [1. 2.718...] |
np.log(x) | natural log (base e) | [1, e] → [0. 1.] |
np.log10(x) | log base 10 | [10, 1000] → [1. 3.] |
np.log2(x) | log base 2 | [8] → [3.] |
np.abs(x) | absolute value (np.absolute) | [-3, 4] → [3 4] |
np.round(x, d) | round to d decimals (half → even) | [2.5, 3.14159], d=0 → [2. 3.] |
np.floor(x) | round down | [2.7, -2.7] → [ 2. -3.] |
np.ceil(x) | round up | [2.1, -2.1] → [ 3. -2.] |
np.trunc(x) | drop decimals (towards 0) | [2.7, -2.7] → [ 2. -2.] |
np.power(x, y) | xʸ (same as **) | ([2, 3], 2) → [4 9] |
np.mod(x, y) | remainder (same as %) | ([7, 10], 3) → [1 1] |
np.maximum(x, y) | larger of each pair | ([4, 1], [2, 5]) → [4 5] |
np.minimum(x, y) | smaller of each pair | ([4, 1], [2, 5]) → [2 1] |
np.sin(x), np.cos(x), np.tan(x) | trigonometry, x in radians | np.sin(np.pi / 2) → 1.0 |
np.add, np.subtract, np.multiply, np.divide | the functions behind + - * / | — |
Example — roots, powers, logs
python
import numpy as np
x = np.array([1, 4, 9, 16, 100])
print("sqrt :", np.sqrt(x))
print("square :", np.square(x))
print("power 3:", np.power(x, 3))
print("log10 :", np.log10(x))
print("log :", np.log(x).round(3))
print("exp :", np.exp(np.array([0, 1, 2])).round(3))text
sqrt : [ 1. 2. 3. 4. 10.]
square : [ 1 16 81 256 10000]
power 3: [ 1 64 729 4096 1000000]
log10 : [0. 0.60205999 0.95424251 1.20411998 2. ]
log : [0. 1.386 2.197 2.773 4.605]
exp : [1. 2.718 7.389]How it works: each function is applied to each element. np.sqrt, np.log and np.exp return floats even for int input. np.log10(100) is 2 because 10² = 100 — logs are used to compress large ranges (e.g. view counts) into small numbers.
Example — absolute value and rounding
python
virat = np.array([72, 45, 88, 31, 64, 0, 103, 52, 19, 77, 41, 93, 28, 66])
rohit = np.array([56, 0, 74, 88, 32, 45, 61, 17, 90, 38, 72, 5, 83, 49])
diff = virat - rohit
print("Difference :", diff)
print("Absolute gap :", np.abs(diff))
avg = (virat + rohit) / 2
print("Average :", avg[:6])
print("round :", np.round(avg[:6]))
print("floor :", np.floor(avg[:6]))
print("ceil :", np.ceil(avg[:6]))
print("Half to even :", np.round(np.array([0.5, 1.5, 2.5, 3.5])))text
Difference : [ 16 45 14 -57 32 -45 42 35 -71 39 -31 88 -55 17]
Absolute gap : [16 45 14 57 32 45 42 35 71 39 31 88 55 17]
Average : [64. 22.5 81. 59.5 48. 22.5]
round : [64. 22. 81. 60. 48. 22.]
floor : [64. 22. 81. 59. 48. 22.]
ceil : [64. 23. 81. 60. 48. 23.]
Half to even : [0. 2. 2. 4.]How it works: np.abs removes the sign, so you see the size of the gap no matter who scored more. floor always goes down, ceil always up. np.round uses "round half to even" (banker's rounding): 0.5 → 0, 1.5 → 2, 2.5 → 2 — this avoids bias when rounding many numbers.
Example — maximum, minimum and mod
python
virat = np.array([72, 45, 88, 31, 64, 0, 103, 52, 19, 77, 41, 93, 28, 66])
rohit = np.array([56, 0, 74, 88, 32, 45, 61, 17, 90, 38, 72, 5, 83, 49])
print("Better score each match:", np.maximum(virat, rohit))
print("Lower score each match :", np.minimum(virat, rohit))
print("Floor scores at 10 :", np.maximum(virat, 10))
print("Even match numbers :", np.arange(1, 15)[np.mod(np.arange(1, 15), 2) == 0])text
Better score each match: [ 72 45 88 88 64 45 103 52 90 77 72 93 83 66]
Lower score each match : [56 0 74 31 32 0 61 17 19 38 41 5 28 49]
Floor scores at 10 : [ 72 45 88 31 64 10 103 52 19 77 41 93 28 66]
Even match numbers : [ 2 4 6 8 10 12 14]How it works: np.maximum compares two arrays position by position and keeps the larger value — very different from np.max, which returns the single largest value of one array. With a scalar, np.maximum(virat, 10) replaces anything below 10 by 10 (a "floor"). The course notebook uses exactly this trick, np.maximum(balls_faced, 1), to avoid dividing by zero.
Example — sin and cos (briefly)
python
angles_deg = np.array([0, 30, 45, 60, 90])
angles_rad = np.deg2rad(angles_deg) # trig ufuncs need radians
print("radians:", angles_rad.round(4))
print("sin :", np.sin(angles_rad).round(4))
print("cos :", np.cos(angles_rad).round(4))text
radians: [0. 0.5236 0.7854 1.0472 1.5708]
sin : [0. 0.5 0.7071 0.866 1. ]
cos : [1. 0.866 0.7071 0.5 0. ]How it works: trigonometric ufuncs expect radians. Convert with np.deg2rad (or np.radians). You'll rarely need these for cricket stats, but they appear in physics, signals and image rotation.
Comparison — np.max vs np.maximum, math vs np
np.max(a) | np.maximum(a, b) | |
|---|---|---|
| Inputs | one array | two arrays (or array + scalar) |
| Output | one number (the largest) | array: larger value at each position |
| Kind | aggregation (reduction) | element-wise ufunc |
math.sqrt | np.sqrt | |
|---|---|---|
| Input | one number | number or array |
sqrt of a list of 1M numbers | needs a loop | one call, fast |
sqrt(-1) | ValueError: math domain error | nan + RuntimeWarning |
Common mistakes
- ❌
math.sqrt(arr)→TypeError: only length-1 arrays can be converted to Python scalars. ✅np.sqrt(arr). - ❌ Using
np.max(a, b)for "larger of each pair" — the 2nd argument is the axis! ✅np.maximum(a, b). - ❌
np.sin(90)expecting 1. ✅np.sin(np.deg2rad(90)). - ❌ Expecting
np.round(2.5)to be 3. ✅ It's2.0(round half to even). - ❌
np.log(0)ornp.log(-1)— gives-inf/nanwith a warning, not an error. Clean your data first.
Interview tip
Q: What is a ufunc? Give examples.
A: A universal function is a vectorized, element-wise NumPy function implemented in C — e.g. np.sqrt, np.exp, np.add, np.maximum. Operators map to ufuncs (a + b → np.add(a, b)). They support broadcasting, out= and where=, and have methods like np.add.reduce (= sum) and np.add.accumulate (= cumsum).
Key points to remember
- A ufunc (universal function) is a fast, element-wise NumPy function written in C; it returns an array of the same shape.
- Unary ufuncs take one array (np.sqrt, np.exp, np.log, np.abs); binary ufuncs take two (np.power, np.mod, np.maximum).
- Operators are ufuncs in disguise: + is np.add, * is np.multiply, ** is np.power, % is np.mod.
- np.floor rounds down, np.ceil rounds up, np.trunc drops decimals, np.round uses round-half-to-even.
- np.maximum(a, b) is element-wise (larger of each pair); np.max(a) returns one number.
- Trig ufuncs (np.sin, np.cos) need radians — convert with np.deg2rad.
- Use np functions, not the math module, on arrays.
Try it yourself
Common ufuncs at a glance
Rounding: round, floor, ceil, trunc
np.maximum vs np.max
Practice: run-rate maths
Revision Flashcards
Tap a card to flip it and see the answer.
