1. Python Pandas Series Fundamentals
CBSE Syllabus Alignment • Subject Code 065
- Data structures in Pandas: Series.
- Creation of Series from – ndarray, dictionary, scalar value.
- Mathematical operations, vectorization, index alignment, and
NaN.- Head and Tail functions, selection, indexing, and slicing.
1. What is a Pandas Series?
A Pandas Series is a one-dimensional labeled array capable of holding any data type (integers, floats, strings, Python objects). It is one of the two foundational data structures in the pandas library (the other being the 2D DataFrame).
Key Architectural Characteristics:
- 1D Data Structure: Contains a single column of data with an explicit index.
- Homogeneous Data: All elements inside a single Series share the same underlying data type (
dtype). - Value Mutable: The data values stored inside the Series can be modified in place.
- Size Immutable: The length/size of an existing Series cannot be changed without creating a new object.
Index Label Data Value
┌─────┐ ┌────────┐
│ 0 │ ───► │ 10.5 │ (float64)
├─────┤ ├────────┤
│ 1 │ ───► │ 20.0 │
├─────┤ ├────────┤
│ 2 │ ───► │ 35.5 │
└─────┘ └────────┘2. Creation of a Series
To use Pandas, import the library using standard convention:
python
import pandas as pd
import numpy as npMethod A: Creation from a Python List or NumPy ndarray
When creating a Series from a list or NumPy array, default zero-based integer index labels 0, 1, 2, ..., n-1 are automatically assigned unless an explicit index list is supplied.
python
import pandas as pd
import numpy as np
# 1. Default integer index
data = [10, 25, 40, 55]
s1 = pd.Series(data)
print(s1)
# Output:
# 0 10
# 1 25
# 2 40
# 3 55
# dtype: int64
# 2. Custom string index
s2 = pd.Series(data, index=['Q1', 'Q2', 'Q3', 'Q4'])
print(s2)
# Output:
# Q1 10
# Q2 25
# Q3 40
# Q4 55
# dtype: int64IMPORTANT
Length Matching Constraint: When specifying a custom index list, the length of the index must strictly equal the length of the data array; otherwise, Pandas raises a ValueError: Length of values does not match length of index.
Method B: Creation from a Python Dictionary
When creating a Series from a dictionary, the dictionary keys become the index labels, and the dictionary values become the Series data elements.
python
marks_dict = {'Aanya': 98, 'Rohan': 85, 'Pooja': 92, 'Kabir': 78}
s_dict = pd.Series(marks_dict)
print(s_dict)
# Output:
# Aanya 98
# Rohan 85
# Pooja 92
# Kabir 78
# dtype: int64Specifying Custom Index with a Dictionary:
If you pass an explicit index argument alongside a dictionary:
- Keys matching the index list are populated with their corresponding values.
- Index labels that do not exist in the dictionary are populated with
NaN(Not a Number / missing value). - Dictionary keys omitted from the index list are ignored.
python
s_filtered = pd.Series(marks_dict, index=['Aanya', 'Pooja', 'Zaid'])
print(s_filtered)
# Output:
# Aanya 98.0
# Pooja 92.0
# Zaid NaN
# dtype: float64TIP
Notice how the dtype automatically converted from int64 to float64 because NaN is internally represented as a floating-point number in Python!
Method C: Creation from a Scalar Constant Value
A single scalar constant can be repeated across multiple indices by passing the scalar value and an explicit index list:
python
s_scalar = pd.Series(100, index=['Term1', 'Term2', 'Term3', 'Term4'])
print(s_scalar)
# Output:
# Term1 100
# Term2 100
# Term3 100
# Term4 100
# dtype: int643. Core Series Attributes
Attributes provide metadata about the Series without using parentheses:
| Attribute | Description | Example Output |
|---|---|---|
s.index | Returns the Index object / labels of the Series | Index(['Q1', 'Q2', 'Q3', 'Q4'], dtype='object') |
s.values | Returns underlying data as a NumPy ndarray | array([10, 25, 40, 55]) |
s.dtype | Returns the data type of the elements | int64 or float64 |
s.shape | Returns a tuple representing the dimensions | (4,) |
s.size | Returns the total number of elements | 4 |
s.ndim | Returns number of dimensions (always 1 for Series) | 1 |
s.nbytes | Returns total bytes consumed by the data | 32 |
s.empty | Returns True if Series contains 0 elements | False |
s.hasnans | Returns True if Series contains at least one NaN | False |
4. Vectorized Mathematical Operations & Index Alignment
Pandas Series support vectorized operations, meaning arithmetic is applied element-by-element without writing explicit Python for loops.
1. Scalar Arithmetic
python
s = pd.Series([10, 20, 30], index=['a', 'b', 'c'])
print(s + 5) # Adds 5 to every element
print(s * 2) # Multiplies every element by 2
print(s > 15) # Returns a boolean Series: [False, True, True]2. Series + Series Arithmetic (Automatic Index Alignment)
When two Series are added, subtracted, multiplied, or divided:
- Elements with matching index labels are combined mathematically.
- Index labels that exist in only one Series produce
NaNin the result.
python
s1 = pd.Series([10, 20, 30], index=['A', 'B', 'C'])
s2 = pd.Series([5, 15, 25], index=['B', 'C', 'D'])
result = s1 + s2
print(result)
# Output:
# A NaN (A only in s1)
# B 25.0 (20 + 5)
# C 45.0 (30 + 15)
# D NaN (D only in s2)
# dtype: float64mermaid
graph TD
subgraph Series 1
A1["A: 10"]
B1["B: 20"]
C1["C: 30"]
end
subgraph Series 2
B2["B: 5"]
C2["C: 15"]
D2["D: 25"]
end
subgraph Result (s1 + s2)
AR["A: NaN"]
BR["B: 25.0 (20+5)"]
CR["C: 45.0 (30+15)"]
DR["D: NaN"]
end
A1 -.-> AR
B1 --> BR
B2 --> BR
C1 --> CR
C2 --> CR
D2 -.-> DR5. Indexing, Slicing & Boolean Subsetting
Positional Indexing vs Label Indexing
python
s = pd.Series([100, 200, 300, 400], index=['p', 'q', 'r', 's'])
# Access single element:
print(s['q']) # Output: 200 (by label)
print(s[1]) # Output: 200 (by position)
# Slicing with positional integers (Stop position is EXCLUDED):
print(s[1:3])
# q 200
# r 300
# dtype: int64
# Slicing with index labels (BOTH start and stop labels are INCLUDED):
print(s['p':'r'])
# p 100
# q 200
# r 300
# dtype: int64WARNING
Crucial CBSE Exam Difference:
- Positional slice
s[0:2]excludes position 2 (returns 2 elements: 0, 1). - Label slice
s['a':'c']includes label 'c' (returns elements for 'a', 'b', 'c').
Boolean Subsetting:
python
marks = pd.Series([45, 88, 92, 33, 76], index=['S1', 'S2', 'S3', 'S4', 'S5'])
# Extract students who passed (marks >= 50):
passed = marks[marks >= 50]
print(passed)
# S2 88
# S3 92
# S5 76
# dtype: int646. Head, Tail & Statistical Methods
head(n) and tail(n):
s.head(n): Returns the firstelements (defaults to if is omitted). s.tail(n): Returns the lastelements (defaults to if is omitted).
python
s = pd.Series(range(10, 70, 10)) # [10, 20, 30, 40, 50, 60]
print(s.head(3)) # Displays elements at indices 0, 1, 2
print(s.tail(2)) # Displays elements at indices 4, 5count() vs len():
len(s): Total number of rows including missing values (NaN).s.count(): Number of non-null values only.
python
s_nan = pd.Series([10, np.nan, 30, np.nan, 50])
print(len(s_nan)) # Output: 5
print(s_nan.count()) # Output: 3Active Recall & Exam Defense
📇 Active Recall Information Practices Deck
Series Indexing & Alignment Flashcard Deck
Card 1 / 5
Unit 1: Pandas DataFrames👆 Click card to reveal equation & mechanism
df.loc vs df.iloc Indexing Behavior
Given DataFrame `df` with custom index `['A', 'B', 'C']`, contrast `df.loc['A':'B']` with `df.iloc[0:2]`.
Recall the equation, boundary limits, and traps before flipping!
✓ Verified Chemistry Formula👆 Click to flip back
📐 Condition / DomainBoth return a DataFrame subset. `df.loc` matches explicit row index labels; `df.iloc` uses zero-based positional integers.
🔍 Boundary Check`df.loc['A':'B']` returns rows A and B. `df.iloc[0:2]` returns rows at positions 0 and 1 (A and B).
⚠️ Common Exam Trap:For integer indices like [1, 2, 3], `df.loc[1:2]` includes row 2, while `df.iloc[1:2]` returns ONLY row at index position 1!
🛡️ Negative-Marking & Output Defense
Spot the Syntax & Output Bug: CBSE IP Code Debugger
Identify the exact line where an illegal syntax, invalid SQL clause, or incorrect index assumption was introduced.
CBSE Problem Statement
Write a query to display the Department and Maximum Salary for departments where the Average Salary exceeds 60,000.
Step-by-Step Code / Output: Click the step that contains the error
Line 1
SELECT Department, MAX(Salary) FROM EmployeeClick to test
Line 2
WHERE AVG(Salary) > 60000Click to test
Line 3
GROUP BY Department;Click to test
⚠️ Pitfall Gallery5 Fatal Series Traps in CBSE Board Exams
Click on each common mistake to see why intuition fails and how examiners trick students:
The False Intuition (Common Mistake):
Thinking that `df.loc[1:3]` and `df.iloc[1:3]` both return 2 rows.
The Physical Truth (What Actually Happens):
`df.iloc[1:3]` uses 0-based integer positions and excludes stop index 3 (returns positions 1 and 2). `df.loc[1:3]` matches index labels and strictly INCLUDES label 3!
⭐ Golden RuleRemember: loc includes BOTH boundary labels; iloc excludes the stop position.