Python for Data course menu
pandas Series Explained: Create, Index and Analyse
Learn the pandas Series: a labelled one-dimensional array, creating a Series from lists and dictionaries, the index, selecting by label and position, vectorised operations, value_counts and handy summary methods.
On this page
pandas is the library for working with tables in Python. It has two core objects:
- a Series: one column of values with labels;
- a DataFrame: a table made of Series that share the same labels (next lesson).
A Series is like a NumPy array with an index: a label for every value.
Creating a Series#
import pandas as pd
temps = pd.Series([22.5, 25.1, 19.8, 27.3])
print(temps)
print(temps.index)
print(temps.values)0 22.5
1 25.1
2 19.8
3 27.3
dtype: float64
RangeIndex(start=0, stop=4, step=1)
[22.5 25.1 19.8 27.3]The left column is the index (0, 1, 2, 3 by default), the right column the values, and the last line shows the dtype. .values gives the underlying NumPy array.
Meaningful labels#
Labels can be anything: names, dates, product codes. Pass them as index, or build the Series from a dictionary:
import pandas as pd
temps = pd.Series([22.5, 25.1, 19.8, 27.3], index=["Mon", "Tue", "Wed", "Thu"], name="temp_c")
print(temps)
print(temps["Wed"])
population = pd.Series({"Mumbai": 12.4, "Delhi": 11.0, "Pune": 3.1})
print(population)Mon 22.5
Tue 25.1
Wed 19.8
Thu 27.3
Name: temp_c, dtype: float64
19.8
Mumbai 12.4
Delhi 11.0
Pune 3.1
dtype: float64Selecting values: loc and iloc#
Because a Series has both labels and positions, pandas gives you two explicit selectors:
.loc[...]selects by label;.iloc[...]selects by position (0, 1, 2, …).
import pandas as pd
temps = pd.Series([22.5, 25.1, 19.8, 27.3], index=["Mon", "Tue", "Wed", "Thu"])
print(temps.loc["Tue"])
print(temps.iloc[0])
print(temps.loc["Tue":"Thu"]) # label slices INCLUDE the end
print(temps.iloc[1:3]) # position slices EXCLUDE the end25.1
22.5
Tue 25.1
Wed 19.8
Thu 27.3
dtype: float64
Tue 25.1
Wed 19.8
dtype: float64Label slices include their end label; position slices work like Python's and exclude the end. Using loc and iloc explicitly avoids ambiguity, especially when the labels are numbers.
Vectorised operations and alignment#
Arithmetic works on every value, like NumPy. When combining two Series, pandas lines them up by label, not by position:
import pandas as pd
temps = pd.Series([22.5, 25.1, 19.8], index=["Mon", "Tue", "Wed"])
print((temps * 9 / 5 + 32).round(1))
jan = pd.Series({"Asha": 120, "Ravi": 90, "Meera": 150})
feb = pd.Series({"Ravi": 110, "Asha": 100, "John": 80})
print(jan + feb)Mon 72.5
Tue 77.2
Wed 67.6
dtype: float64
Asha 220.0
John NaN
Meera NaN
Ravi 200.0
dtype: float64"Asha" is matched with "Asha" even though the order differs. Names present in only one Series get NaN (missing), because there is nothing to add. Use jan.add(feb, fill_value=0) to treat missing as zero.
Filtering and summarising#
import pandas as pd
scores = pd.Series([88, 72, 95, 64, 81], index=["Asha", "Ravi", "Meera", "John", "Priya"])
print(scores[scores >= 80])
print(scores.mean(), scores.max(), scores.idxmax())
print(scores.sort_values(ascending=False).head(3))
print(scores.describe())Asha 88
Meera 95
Priya 81
dtype: int64
80.0 95 Meera
Meera 95
Asha 88
Priya 81
dtype: int64
count 5.000000
mean 80.000000
std 12.349089
min 64.000000
25% 72.000000
50% 81.000000
75% 88.000000
max 95.000000
dtype: float64idxmax() returns the label of the maximum. describe() gives a quick statistical summary.
Counting categories#
value_counts is one of the most used methods in pandas: how many times each value appears.
import pandas as pd
payment = pd.Series(["card", "upi", "cash", "upi", "card", "upi"])
print(payment.value_counts())
print(payment.value_counts(normalize=True).round(2))
print(payment.nunique(), payment.unique())upi 3
card 2
cash 1
Name: count, dtype: int64
upi 0.50
card 0.33
cash 0.17
Name: proportion, dtype: float64
3 ['card' 'upi' 'cash']normalize=True gives proportions instead of counts.
Common mistakes#
Practice#
Practice exercise
Monthly expenses are {"rent": 15000, "food": 6200, "travel": 1800, "phone": 600, "fun": 2400}. Create a Series, print the total, the share of each category as a percentage (rounded to 1 decimal), and the categories above 2000 sorted from largest to smallest.
Show hint
Divide the Series by its sum and multiply by 100. Filter with a boolean condition, then sort_values(ascending=False).
Show solution
import pandas as pd
expenses = pd.Series({"rent": 15000, "food": 6200, "travel": 1800, "phone": 600, "fun": 2400})
print(expenses.sum())
print((expenses / expenses.sum() * 100).round(1))
print(expenses[expenses > 2000].sort_values(ascending=False))26000
rent 57.7
food 23.8
travel 6.9
phone 2.3
fun 9.2
dtype: float64
rent 15000
food 6200
fun 2400
dtype: int64Key takeaway#
Next: whole tables, in DataFrames.
Finished this lesson?