Pandas is the most popular Python library for working with tabular data (like spreadsheets, CSV files, and SQL tables). It allows you to load, inspect, clean, and analyze datasets in just a few lines of code.
In this beginner-friendly guide, you will learn the two core building blocks of Pandas—Series and DataFrame—how to read and write CSV files, and how to clean a messy
weather dataset (data.csv) step by step.
What is Pandas?
Pandas stands for "Panel Data" and is built on top of NumPy. You can install it from your terminal using pip:
pip install pandas
Once installed, import it in your Python script using the standard alias pd:
import pandas as pd
What is a Pandas Series?
A Pandas Series is like a single column in a table. It is a one-dimensional array holding data of any type (integers, floats, or strings), where every item has an index
label (starting at 0 by default).
import pandas as pd
# Creating a Series of maximum temperatures
temps = [32.5, 34.0, 31.2, 35.8]
max_temp_series = pd.Series(temps)
print(max_temp_series)
print("First value:", max_temp_series[0])
You can also give custom labels to a Series using the index parameter:
single_day = pd.Series([34.0, 22.5], index=["maxtemp", "mintemp"])
print(single_day["maxtemp"]) # Output: 34.0
What is a Pandas DataFrame?
While a Series is a single column, a DataFrame is a whole table with rows and columns—just like an Excel sheet or a database table. Under the hood, a
DataFrame is a collection of Series that share the same row index.
import pandas as pd
weather_data = {
"maxtemp": [34.2, 35.0, 33.1],
"mintemp": [22.1, 23.4, 21.8],
"day": [1, 2, 3],
"month": [5, 5, 5],
"year": [2026, 2026, 2026],
}
df = pd.DataFrame(weather_data)
print(df)
Use df.loc[0] to get a single row, or df["maxtemp"] to get a single column as a Series.
Read and write operations with data.csv
In real projects, you rarely type data by hand. Instead, you load it from a CSV (Comma-Separated Values) file using pd.read_csv() and save it back using df.to_csv().
Suppose we have a messy weather file named data.csv with the columns maxtemp, mintemp, day, month, and year:
maxtemp,mintemp,day,month,year
34.5,22.0,1,5,2026
36.0,,2,5,2026
"35.2C",23.5,3,5,2026
410.0,24.0,4,5,2026
33.8,21.5,5,May,2026
33.0,21.0,6,5,2026
33.0,21.0,6,5,2026
,20.5,7,5,2026
What is wrong with this dataset?Look closely at data.csv: row 1 and row 7 have empty cells, row 2 has "35.2C" and row 4 has
"May" (wrong format), row 3 has 410.0 degrees (wrong data typo for 41.0), and row 5 & 6 are
duplicates.
Reading the CSV and inspecting it
Use pd.read_csv() to load the file, then use head(), tail(), and info() to inspect it:
import pandas as pd
df = pd.read_csv("data.csv")
print("--- Full DataFrame ---")
print(df)
print("\n--- Data Info ---")
print(df.info())
Writing a DataFrame to CSV
Whenever you want to export your DataFrame to a new CSV file, use to_csv(). Pass index=False so Pandas does not write the row numbers (0, 1, 2...) as an extra
column:
df.to_csv("output.csv", index=False)
1. Cleaning empty cells
Pandas represents empty cells as NaN (Not a Number). In our data.csv, row 1 has a missing mintemp and row 7 has a missing
maxtemp. You have two ways to handle empty cells:
Option A: Remove rows with empty cells using dropna()
If your dataset is huge, dropping a few incomplete rows is often the simplest choice:
# Returns a new DataFrame with all rows containing NaN removed
df_no_nulls = df.dropna()
# Or drop only if 'mintemp' is empty:
df_no_nulls = df.dropna(subset=["mintemp"])
Option B: Replace empty cells using fillna()
Instead of deleting an entire row, you can fill empty cells with a fixed number or with the column's mean (average) or median:
# Fill missing mintemp with the average (mean) minimum temperature
mean_min = df["mintemp"].mean()
df["mintemp"] = df["mintemp"].fillna(round(mean_min, 1))
print(df[["day", "mintemp"]])
2. Cleaning data of wrong format
Cells with the wrong format make math impossible. In data.csv:
- Row 2 has
"35.2C"inmaxtemp(because of the letterC, Pandas treats the wholemaxtempcolumn as text instead of numbers). - Row 4 has
"May"inmonthinstead of the number5.
We can strip unwanted text, replace month names, and convert columns to numeric types using pd.to_numeric(). We can also combine year, month, and
day into a real datetime column using pd.to_datetime():
# 1. Remove trailing 'C' from maxtemp and convert to float
df["maxtemp"] = df["maxtemp"].astype(str).str.replace("C", "", regex=False)
df["maxtemp"] = pd.to_numeric(df["maxtemp"], errors="coerce")
# 2. Replace "May" with 5 in month and convert to integer
df["month"] = df["month"].replace({"May": 5})
df["month"] = pd.to_numeric(df["month"], errors="coerce").astype("int64")
# 3. Fill any remaining NaN in maxtemp with the median
df["maxtemp"] = df["maxtemp"].fillna(df["maxtemp"].median())
# 4. Optional: Create a proper date column from year, month, day
df["date"] = pd.to_datetime(df[["year", "month", "day"]])
print(df[["date", "maxtemp", "mintemp"]])
3. Fixing wrong data
"Wrong data" does not have to be an empty cell or a text string—it can be a valid number that makes no sense in the real world. In row 3, maxtemp is recorded as
410.0 degrees Celsius, most likely a missing decimal point for 41.0.
Fixing a specific cell
For small datasets, you can fix the exact row and column directly using df.loc[row_index, "column_name"]:
df.loc[3, "maxtemp"] = 41.0
Fixing wrong data with rules (for large datasets)
For large files, you can write a rule to detect unrealistic temperatures (for example, any maxtemp > 60) and either cap them, divide by 10, or drop those rows:
# Rule: If maxtemp is over 60°C, divide by 10 to fix missing decimal typos
outlier_mask = df["maxtemp"] > 60
df.loc[outlier_mask, "maxtemp"] = df.loc[outlier_mask, "maxtemp"] / 10
# Or if you want to remove rows where maxtemp is less than mintemp:
df = df[df["maxtemp"] >= df["mintemp"]]
4. Removing duplicate data
Duplicate rows skew averages and totals. In our dataset, rows 5 and 6 (`day = 6, month = 5, year = 2026`) are identical.
Use df.duplicated() to spot duplicates (returns True for duplicate rows), and df.drop_duplicates() to remove them:
# Check which rows are duplicates
print(df.duplicated())
# Remove duplicate rows and reset the row index (0, 1, 2...)
df = df.drop_duplicates().reset_index(drop=True)
print(df)
Complete data cleaning script
Here is the complete, copy-pasteable Python script that loads data.csv, cleans empty cells, fixes wrong formats, corrects wrong temperature values, drops duplicates, and saves the result
to cleaned_data.csv:
import pandas as pd
# 1. Read the messy CSV file
df = pd.read_csv("data.csv")
# 2. Clean Wrong Format: strip 'C' from maxtemp and replace 'May' in month
df["maxtemp"] = df["maxtemp"].astype(str).str.replace("C", "", regex=False)
df["maxtemp"] = pd.to_numeric(df["maxtemp"], errors="coerce")
df["month"] = df["month"].replace({"May": 5})
df["month"] = pd.to_numeric(df["month"], errors="coerce").astype("int64")
# 3. Clean Wrong Data: fix missing decimal point if maxtemp > 60
outliers = df["maxtemp"] > 60
df.loc[outliers, "maxtemp"] = df.loc[outliers, "maxtemp"] / 10
# 4. Clean Empty Cells: fill missing temperatures with column averages
df["maxtemp"] = df["maxtemp"].fillna(round(df["maxtemp"].mean(), 1))
df["mintemp"] = df["mintemp"].fillna(round(df["mintemp"].mean(), 1))
# 5. Remove Duplicates
df = df.drop_duplicates().reset_index(drop=True)
# 6. Write the clean DataFrame to a new CSV file
df.to_csv("cleaned_data.csv", index=False)
print(df)