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.