NumPy: Element-wise Operations

Last updated: 2026-08-26

1. What You'll Learn



2. Story

Bob uses a for loop to square 1 million numbers — it takes 0.3 seconds. Alice writes one line a ** 2 — 3 milliseconds.

"NumPy arithmetic isn't a Python loop. It's a C-level ufunc batch operation, 100x faster."

Bob asks: "What's a ufunc?" Alice opens her terminal and types np.add — it all starts with element-wise operations.



3. Key Concepts

(1) Arithmetic Operators and Functions

NumPy arithmetic operates on every element of the array, automatically broadcasting shapes:

PYTHON
import numpy as np

a = np.array([1, 2, 3, 4])
b = np.array([10, 20, 30, 40])

print(a + b)      # [11 22 33 44]
print(a * b)      # [10 40 90 160]
print(a ** 2)     # [ 1  4  9 16]
print(b // a)     # [10 10 10 10]
print(b % a)      # [0 0 0 0]
TEXT 📖 Display only
> **Output:** Run NumPy 2.x in your local Python environment to see the ndarray output. The Piston server does not have NumPy pre-installed — install it locally (`pip install numpy`) and compare. Actual values may vary by NumPy version and random seed.
⚠️ Note: The code below needs to run in a local Python environment.

Each operator corresponds to a NumPy function:

Operator Function Description
+ np.add Addition
- np.subtract Subtraction
* np.multiply Multiplication
/ np.true_divide True division
// np.floor_divide Floor division
% np.mod Modulo
** np.power Power

(2) Comparison Operations

Comparisons are element-wise, returning boolean arrays (masks):

PYTHON
a = np.array([3, 7, 1, 9, 5])

print(a > 4)           # [False  True False  True  True]
print(a == 7)          # [False  True False False False]
print((a >= 3) & (a <= 7))  # [ True  True False False  True]
TEXT 📖 Display only
> **Output:** Run NumPy 2.x in your local Python environment to see the ndarray output. The Piston server does not have NumPy pre-installed — install it locally (`pip install numpy`) and compare. Actual values may vary by NumPy version and random seed.
⚠️ Note: The code below needs to run in a local Python environment.

(3) Logical Operations

Use bitwise operators & | ^ ~ (not and or not) for element-wise logical combinations:

PYTHON
a = np.array([True, True, False, False])
b = np.array([True, False, True, False])

print(a & b)                # [ True False False False]
print(a | b)                # [ True  True  True False]
print(~a)                   # [False False  True  True]
print(np.logical_and(a, b)) # [ True False False False]
TEXT 📖 Display only
> **Output:** Run NumPy 2.x in your local Python environment to see the ndarray output. The Piston server does not have NumPy pre-installed — install it locally (`pip install numpy`) and compare. Actual values may vary by NumPy version and random seed.
⚠️ Note: The code below needs to run in a local Python environment.

(4) ufunc Concept

ufunc (universal function) is NumPy's low-level abstraction for element-wise operations:

PYTHON
print(np.add.nin)   # 2 (number of inputs)
print(np.add.nout)  # 1 (number of outputs)
print(np.add.types) # list of supported type signatures
TEXT 📖 Display only
> **Output:** Run NumPy 2.x in your local Python environment to see the ndarray output. The Piston server does not have NumPy pre-installed — install it locally (`pip install numpy`) and compare. Actual values may vary by NumPy version and random seed.
⚠️ Note: The code below needs to run in a local Python environment.


▶ Example

TEXT 📖 Display only
> **Output:** Run NumPy 2.x in your local Python environment to see the ndarray output. The Piston server does not have NumPy pre-installed — install it locally (`pip install numpy`) and compare. Actual values may vary by NumPy version and random seed.

: Arithmetic operations (Difficulty ⭐)

PYTHON
import numpy as np

a = np.array([2, 4, 6, 8])
b = np.array([1, 3, 5, 7])

print("a + b =", a + b)        # [ 3  7 11 15]
print("a - b =", a - b)        # [1 1 1 1]
print("a * b =", a * b)        # [ 2 12 30 56]
print("a / b =", a / b)        # [2.   1.33 1.2  1.14]
print("a // b =", a // b)      # [2 1 1 1]
print("a % b =", a % b)        # [0 1 1 1]
print("a ** 3 =", a ** 3)      # [  8  64 216 512]
TEXT 📖 Display only
> **Output:** Run NumPy 2.x in your local Python environment to see the ndarray output. The Piston server does not have NumPy pre-installed — install it locally (`pip install numpy`) and compare. Actual values may vary by NumPy version and random seed.
⚠️ Note: The code below needs to run in a local Python environment.

▶ Example

TEXT 📖 Display only
> **Output:** Run NumPy 2.x in your local Python environment to see the ndarray output. The Piston server does not have NumPy pre-installed — install it locally (`pip install numpy`) and compare. Actual values may vary by NumPy version and random seed.

: Comparison masks (Difficulty ⭐)

PYTHON
import numpy as np

scores = np.array([55, 82, 91, 47, 73, 100])

pass_mask = scores >= 60
print("Pass mask:", pass_mask)
print("Pass scores:", scores[pass_mask])

excellent = scores >= 90
print("Excellent:", scores[excellent])

mid_range = (scores >= 60) & (scores < 90)
print("Mid-range:", scores[mid_range])
TEXT 📖 Display only
> **Output:** Run NumPy 2.x in your local Python environment to see the ndarray output. The Piston server does not have NumPy pre-installed — install it locally (`pip install numpy`) and compare. Actual values may vary by NumPy version and random seed.
⚠️ Note: The code below needs to run in a local Python environment.

▶ Example: Using ufunc out parameter (Difficulty ⭐⭐)

PYTHON
import numpy as np

a = np.array([10, 20, 30, 40])
b = np.array([3, 4, 5, 6])

# In-place addition using out parameter
result = np.empty(4)
np.add(a, b, out=result)
print("Result:", result)

# Chain operations with out
np.multiply(result, 2, out=result)
print("Doubled:", result)

# Comparison ufunc
print("a > 15:", np.greater(a, 15))

Output:

TEXT 📖 Display only
Result: [13 24 35 46]
Doubled: [26 48 70 92]
a > 15: [False  True  True  True]


❓ FAQ

Q Why use np.add instead of +?
A They're identical — + calls np.add under the hood. Use the function form when you need extra parameters like dtype, out, or where, or when passing a ufunc as a callback.
Q Does division by zero raise an error?
A No exception for floats — it produces inf or -inf, and 0/0 produces nan, with an optional warning based on np.seterr. Integer division by zero raises ZeroDivisionError.
Q Is vectorization always faster than loops?
A For large arrays with simple operations, vectorization is typically 50-200x faster. But for very small arrays (<100 elements), the ufunc call overhead can make it slower than a loop.
Q What is a ufunc?
A A universal function — a C-level wrapper for element-wise operations. Each ufunc handles broadcasting, type promotion, and output buffering automatically. It's the engine behind NumPy's vectorization.

📖 Summary



📝 Exercises

  1. Beginner (Difficulty ⭐): Create x = np.linspace(-5, 5, 100). Compute the sigmoid function 1 / (1 + np.exp(-x)) using vectorization. Count how many results are > 0.5.

  2. Intermediate (Difficulty ⭐⭐): Compute np.sin(x) for 1 million random numbers using both a for loop and vectorization. Compare the time and calculate the speedup factor.

  3. Advanced (Difficulty ⭐⭐⭐): Implement a vectorized ReLU function max(0, x) for x = np.linspace(-3, 3, 20). Implement it using both a boolean mask x * (x > 0) and np.maximum(0, x).

Web-Tutorial.com

Web-Tutorial Tech Team

A team of developers maintaining programming tutorials. Each tutorial is written and reviewed by developers with expertise in that field. We work to keep our content accurate and reliable — if you spot an issue, please let us know.

100%

🙏 帮我们做得更好

我们是刚上线的编程教程站,几个人的小团队,精力有限。页面虽经检查,难免还有疏漏——链接失效、排版错乱、内容有误、语言生硬……

如果您发现了,麻烦告诉我们,我们会在收到反馈后第一时间进行修复,再次感谢您的光临 🙏