Vectorized Operations on Series
Perform arithmetic between two Series, handle index alignment automatically, and fill missing aligned values with NaN.
Vectorized Operations on Series is a free Pandas & NumPy Academy lesson on CoddyKit — lesson 3 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the Pandas & NumPy Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.
Why Vectorized Operations?
Like NumPy, Pandas Series support vectorized operations that apply arithmetic, comparisons, and functions to every element without Python loops. This provides both conciseness and speed. Under the hood each operation delegates to NumPy's C-level routines, but Pandas adds a critical bonus: automatic index alignment before performing the operation.
import pandas as pd
revenue = pd.Series([1000, 2000, 1500], index=['Jan', 'Feb', 'Mar'])
tax_rate = 0.2
net = revenue * (1 - tax_rate) # vectorized -- no loop
print(net)Arithmetic Between Two Series
When you add, subtract, multiply, or divide two Series, Pandas aligns them by index label first. Only positions where both Series have a label produce a result; unmatched labels produce NaN. This behaviour prevents hidden bugs from mis-aligned data — for example, adding January figures from two data sources that happen to be stored in different orders.
import pandas as pd
a = pd.Series([10, 20, 30], index=['x', 'y', 'z'])
b = pd.Series([1, 2, 3], index=['y', 'z', 'w'])
print(a + b)
# w NaN
# x NaN
# y 21.0
# z 32.0Filling NaN in Aligned Operations
To avoid NaN propagation in misaligned operations, use the arithmetic methods like .add(), .sub(), .mul(), and .div() with the fill_value= parameter. This substitutes a given value for any label that is missing in one of the Series before performing the operation — commonly 0 for addition and 1 for multiplication.
import pandas as pd
a = pd.Series([10, 20, 30], index=['x', 'y', 'z'])
b = pd.Series([1, 2, 3], index=['y', 'z', 'w'])
result = a.add(b, fill_value=0)
print(result)
# w 3.0
# x 10.0
# y 21.0
# z 32.0Scalar Arithmetic on a Series
Arithmetic with a scalar applies the operation to every element and produces a new Series with the same index. This is the simplest form of vectorization: s + 5, s * 100, s ** 2. Scalar arithmetic never introduces NaN and is used for unit conversion, normalisation, and offsetting time series.
import pandas as pd
prices_eur = pd.Series([1.0, 2.5, 4.0], index=['a', 'b', 'c'])
exchange = 1.08
prices_usd = prices_eur * exchange
print(prices_usd.round(2))
# a 1.08
# b 2.70
# c 4.32Applying NumPy ufuncs to Series
NumPy ufuncs work seamlessly on Pandas Series and return a Series with the same index. This means you can call np.sqrt(s), np.log1p(s), or np.exp(s) directly on a Series without converting to an array first. The result is a new Series, preserving the original labels.
import pandas as pd
import numpy as np
s = pd.Series([0, 1, 4, 9, 16], index=list('abcde'))
print(np.sqrt(s))
# a 0.0
# b 1.0
# c 2.0
# d 3.0
# e 4.0Comparison Operations on Series
Comparison operators (==, !=, >, <, >=, <=) return a boolean Series element-wise. These are the building blocks for filtering: you pass the boolean Series to .loc to select the matching rows. Pandas also aligns by index when comparing two Series.
import pandas as pd
s = pd.Series([3, 7, 2, 9, 1], index=list('abcde'))
print(s > 4)
# a False
# b True
# c False
# d True
# e False
print(s[s > 4]) # b:7 d:9Chaining Vectorized Operations
Because each operation returns a new Series, you can chain multiple transformations in a single expression. This is readable and avoids creating unnecessary intermediate variables. For complex pipelines, break the chain across lines using parentheses. Chaining is the Pandas equivalent of functional programming with immutable data.
import pandas as pd
import numpy as np
raw_scores = pd.Series([55, 80, 45, 90, 72])
normalised = (raw_scores - raw_scores.min()) / (raw_scores.max() - raw_scores.min())
print(normalised.round(2))
# 0 0.22
# 1 0.78
# 2 0.00
# 3 1.00
# 4 0.60Handling NaN in Vectorized Operations
NaN is contagious: any arithmetic involving NaN produces NaN. Use s.fillna(value) to substitute before operating, or use the skipna=True parameter on aggregation methods. The pd.isna(s) function returns a boolean Series marking NaN positions — use it to audit data before computing statistics.
import pandas as pd
import numpy as np
s = pd.Series([1.0, np.nan, 3.0, np.nan, 5.0])
print(s + 10)
# 0 11.0 2 13.0 4 15.0 -- NaN stays NaN
print(s.fillna(0) + 10)
# 0 11.0 1 10.0 2 13.0 3 10.0 4 15.0abs(), clip(), and round() on Series
Pandas Series expose many NumPy-like methods directly: s.abs(), s.clip(lower, upper), and s.round(decimals) all return new Series with the transformation applied element-wise. These are equivalent to the NumPy ufunc calls but use method syntax and preserve the Series index and name.
import pandas as pd
s = pd.Series([-2.5, 1.3, -0.7, 4.9, -3.1])
print(s.abs()) # [2.5 1.3 0.7 4.9 3.1]
print(s.clip(-2, 2)) # [-2. 1.3 -0.7 2. -2. ]
print(s.round(0)) # [-2. 1. -1. 5. -3.]pct_change() for Growth Rates
s.pct_change() computes the percentage change between consecutive elements: (current - previous) / previous. The first element is NaN since there is no previous value. This is the standard operation for computing month-over-month growth rates, daily returns in finance, and rate-of-change features for time series models.
import pandas as pd
monthly_revenue = pd.Series([100, 120, 110, 140],
index=['Q1', 'Q2', 'Q3', 'Q4'])
growth = monthly_revenue.pct_change()
print(growth.round(3))
# Q1 NaN
# Q2 0.200
# Q3 -0.083
# Q4 0.273cumsum() and cumprod() on Series
s.cumsum() returns a Series of running totals and s.cumprod() returns running products. These are used to compute cumulative revenue, compound investment returns, or running word counts. They preserve the original index labels, making it easy to plot the cumulative series over time or category.
import pandas as pd
daily_sales = pd.Series([100, 150, 80, 200],
index=['Mon', 'Tue', 'Wed', 'Thu'])
print(daily_sales.cumsum())
# Mon 100
# Tue 250
# Wed 330
# Thu 530Quick Check
Test your understanding of vectorized operations on Series from this lesson.
Lesson Recap
In this lesson you learned: arithmetic operators apply element-wise to Series without loops, Pandas automatically aligns two Series by index label before operating, placing NaN at unmatched positions, and methods like fill_value, pct_change, and cumsum extend vectorized operations for analytical tasks. Next up we explore useful Series methods like describe, value_counts, and map for rapid summarisation.
Frequently asked questions
Is the “Vectorized Operations on Series” lesson free?
Yes — the full text of “Vectorized Operations on Series” is free to read here on the web, and the Pandas & NumPy Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the Pandas & NumPy Academy course, upgrade to CoddyKit PRO.
What will I learn in “Vectorized Operations on Series”?
Perform arithmetic between two Series, handle index alignment automatically, and fill missing aligned values with NaN. You practise Pandas & NumPy Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.
Do I need any experience to start Pandas & NumPy Academy?
No prior experience is required. Pandas & NumPy Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 3 of 4, so you can start here or from the beginning and move at your own pace.
How long does the “Vectorized Operations on Series” lesson take?
Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.
Can I write and run code in this Pandas & NumPy Academy lesson?
Yes. Every Pandas & NumPy Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.
All lessons in this course
- Creating a Series
- Label-Based and Position-Based Access
- Vectorized Operations on Series
- Useful Series Methods