Element-wise Operations & Universal Functions
A universal function (ufunc) is a NumPy function that applies the same operation to every element of an array at once, running in compiled C — element-wise operations like + , np.sqrt , and np.exp are all ufuncs.
Learn Element-wise Operations & Universal Functions in our free NumPy course — a beginner-friendly interactive lesson with worked examples, a practice…
Part of the free Numpy course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.
In this lesson you'll use arithmetic ufuncs, math ufuncs like np.sqrt and np.log , see that np.add(a, b) equals a + b , run comparison ufuncs, and meet the out parameter.
A universal function , or ufunc , is a function that runs element-by-element over an entire array in fast, compiled C code. Because the loop happens inside C rather than Python, ufuncs are dramatically faster than writing your own for loop.
You've already used ufuncs without knowing it: every arithmetic operator on an array is one.
Expected output: [11 12 13 14] , [0 1 2 3] , [2 4 6 8] , [0.5 1. 1.5 2. ] , and [ 1 4 9 16] .
NumPy ships hundreds of math ufuncs. Each one applies its function to every element and returns a new array. The most common are np.sqrt (square root), np.exp (e x ), np.log (natural log), and the trig functions like np.sin .
Expected output: [1. 2. 3. 4.] , the exponentials [1. 2.718... 7.389...] , [0. 1.] for the logs, and [0. 1.] for the sines.
The operators are convenient aliases for named ufuncs. a + b calls np.add(a, b) , a * b calls np.multiply(a, b) , and so on. They give identical results — and the named form is what lets you pass extra options like out .
Expected output: [11 22 33] twice, [10 40 90] twice, and True .
Comparisons like a > b are ufuncs too — they return a boolean array, element by element. And most ufuncs accept an out argument to write the result into an existing array instead of allocating a new one, which saves memory on large data.
Expected output: [False True False] , [False False True] , [3. 9. 6.] , then [ 6 10 8] and [3 9 6] .
Replace each ___ so the program squares, square-roots, and adds two arrays.
Expected output: [ 1 4 9 16] , [3. 4.] , and [4 6] . (Answers: ** , sqrt , add .)
❌ TypeError: only size-1 arrays can be converted to Python scalars
You called math.sqrt(arr) from the standard library on a whole array.
✅ Fix: use the ufunc np.sqrt(arr) , which handles every element.
❌ ValueError: operands could not be broadcast together
You added two arrays of mismatched shapes element-wise.
✅ Fix: make the shapes match, or add a scalar like arr + 5 .
Given x and y coordinates, compute each point's distance from the origin using ufuncs: sqrt(x² + y²).
Lesson 9 complete — math at C speed!
You now know what a ufunc is, use arithmetic and math ufuncs across whole arrays, understand that np.add(a, b) equals a + b , run comparison ufuncs, and can route results through the out parameter.
🚀 Up next: Broadcasting Explained — how NumPy combines arrays of different shapes.
Practice quiz
What is a universal function (ufunc) in NumPy?
- A function that only works on scalars
- A function that runs element-by-element across an array in compiled C
- A plotting helper
- A way to read files
Answer: A function that runs element-by-element across an array in compiled C. A ufunc applies the same operation to every element at once, in fast C.
What does arr + 10 do for arr = [1, 2, 3, 4]?
- Raises an error
- Appends 10
A scalar is applied element-wise, adding 10 to each value.
Is a + b the same as np.add(a, b)?
- Yes, the operator is a shortcut for the ufunc
- No, results differ
- Only for floats
- Only for 1D arrays
Answer: Yes, the operator is a shortcut for the ufunc. The arithmetic operators are friendly aliases for the named ufuncs.
Why use np.sqrt(arr) instead of math.sqrt(arr)?
- np.sqrt is slower
- They are identical
- math.sqrt is more accurate
- math.sqrt only works on one number, np.sqrt works on a whole array
Answer: math.sqrt only works on one number, np.sqrt works on a whole array. np.sqrt handles every element; math.sqrt errors on an array.
What does a comparison ufunc like a > b return?
- A single True/False
- A boolean array, element by element
- An integer count
- The larger array
Answer: A boolean array, element by element. Comparisons are ufuncs that return a boolean array of the same shape.
What does the out parameter of a ufunc do?
- Prints the result
- Reverses the array
- Writes the result into an existing array instead of allocating a new one
- Sorts the output
Answer: Writes the result into an existing array instead of allocating a new one. out= reuses an existing buffer, saving memory on large arrays.
What does np.sqrt([1, 4, 9, 16]) return?
Element-wise square roots give [1. 2. 3. 4.].
What does 'element-wise' mean?
- Operating on the whole array as one value
- Sorting the elements
- Removing duplicates
- Operating on each matching pair of elements independently
Answer: Operating on each matching pair of elements independently. a + b adds a[0]+b[0], a[1]+b[1], and so on, position by position.
What does arr ** 2 produce for arr = [1, 2, 3, 4]?
** raises each element to the power 2 element-wise.
What does np.add(a, b, out=res) do?
- Returns a new array only
- Stores the element-wise sum into res
- Subtracts b from a
- Compares a and b
Answer: Stores the element-wise sum into res. It writes the sum a+b into the existing array res.