Series
pandas.Series is a labelled 1-D array. Index + values + dtype. The unit underneath every DataFrame column.
Pandas — Series
EXAMPLE
import pandas as pd
import numpy as np
# ===== Creation =====
s = pd.Series([10, 20, 30, 40], index=['a', 'b', 'c', 'd'])
print(s)
# Default integer index:
s2 = pd.Series([1, 2, 3])
# 0 1
# 1 2
# 2 3
# From a dict (key -> index, value -> values):
s3 = pd.Series({'a': 1, 'b': 2, 'c': 3})
# ===== Attributes =====
s.dtype # int64
s.index # Index(['a', 'b', 'c', 'd'])
s.values # np.array([10, 20, 30, 40])
s.shape # (4,)
s.name = 'amount'
# ===== Indexing =====
s['a'] # 10 (label)
s.iloc[0] # 10 (position)
s[['a', 'c']] # subset
# Slicing — labels INCLUSIVE on both ends:
s['a':'c']
# Boolean mask:
s[s > 15]
# ===== Vectorised math =====
s + 1
s * 2
s ** 0.5
np.log(s)
s + pd.Series([100, 200], index=['a', 'b'])
# Adds where index matches; NaN elsewhere.
# ===== Stats =====
s.mean(), s.std(), s.min(), s.max()
s.sum(), s.cumsum(), s.cummax()
s.quantile(0.95)
s.describe()
# ===== Missing data =====
s4 = pd.Series([1.0, np.nan, 3.0])
s4.isna() # [F, T, F]
s4.fillna(0)
s4.dropna()
s4.interpolate()
# ===== String operations (.str accessor) =====
names = pd.Series(['Alex', 'Sam', 'Lee'])
names.str.lower()
names.str.contains('a', case=False)
names.str.len()
# ===== Date operations (.dt accessor) =====
dates = pd.to_datetime(pd.Series(['2024-04-10', '2024-04-11']))
dates.dt.year
dates.dt.day_name()
dates.dt.tz_localize('Australia/Sydney')
# ===== Categorical for low-cardinality strings =====
cats = pd.Series(['a', 'b', 'a', 'c'], dtype='category')
cats.cat.categories
cats.memory_usage()
# ===== map vs apply =====
# map: per-element transform, simple
s.map(lambda x: x * 10)
s.map({'a': 'A', 'b': 'B'}) # also lookup-table style
# apply: more flexible, also per-element
s.apply(lambda x: x ** 2)
# ===== Conversion to + from numpy =====
arr = s.to_numpy()
s5 = pd.Series(arr, index=['a','b','c','d'], name='amt')
# ===== Patterns to internalise =====
# - dtype matters: int64 / float64 / category / datetime64[ns]
# - .iloc for position, [] / .loc for labels
# - Use .str / .dt accessors over Python loops
# - Convert low-cardinality strings to 'category' to save memory
# ===== Pitfalls =====
# - Mixing label and position indexing
# - Implicit alignment when adding series with different indexes -> surprise NaNs
# - SettingWithCopyWarning when assigning into a sliced view
# - .apply with a Python function on a hot column -> slow; reach for vectorised
Why it matters
Series is the building block. Index + values + dtype + a million vectorised methods. Master indexing (.iloc vs .loc), the .str / .dt accessors, and the dtype game, and Pandas at the DataFrame level becomes a series of these moves in concert.
Tip: Tweak the snippet with Try it Yourself », then sit the quiz at the bottom of the page.
Example
Example
import pandas as pd s = pd.Series([10, 20, 30], index=['a','b','c']) print(s) print(s['b']) # 20Try it Yourself »
Exercise
Pandas alias convention.
import pandas as
Two letters.
Discussion
Loading…