Skip to content

Dataset Guide — COVID-19 Data Analysis

Source

Dataset: Our World in Data (OWID) COVID-19 Dataset URL: https://github.com/owid/covid-19-data/tree/master/public/data File: owid-covid-data.csv Granularity: One row per country per day Period: Jan 2020 onwards

Why OWID?

Our World in Data aggregated, cleaned, and standardised COVID data from official sources worldwide. It's the gold standard for cross-country comparison and includes per-capita and rolling-average columns already computed — though you'll learn to compute them yourself.


Key Column Descriptions

Column Type Description
iso_code str Country ISO code
continent str Continent (NULL for aggregates like "World")
location str Country/region name
date date Reporting date
total_cases float Cumulative confirmed cases
new_cases float New cases that day
new_cases_smoothed float 7-day rolling average of new cases
total_deaths float Cumulative deaths
new_deaths float New deaths that day
new_deaths_smoothed float 7-day rolling average of deaths
total_cases_per_million float Cumulative cases per 1M population
new_cases_per_million float Daily cases per 1M
total_deaths_per_million float Cumulative deaths per 1M
people_vaccinated float People with ≥1 dose
people_fully_vaccinated float People fully vaccinated
total_vaccinations_per_hundred float Doses per 100 people
population float Country population
median_age float Median age of population
gdp_per_capita float GDP per capita
hospital_beds_per_thousand float Healthcare capacity proxy

Critical Data Concepts

Cumulative vs Daily

total_cases is a running total — it only ever goes up. new_cases is the daily value. Don't sum total_cases across days (you'd be summing running totals — meaningless). To get a period total, sum new_cases.

Aggregate rows are mixed in

The dataset includes rows where location is "World", "Europe", "High income", etc. These have NULL continent. Filter them out when analysing individual countries, or you'll double-count.

Per-capita is essential for comparison

Comparing total_cases between the US (330M people) and Iceland (370k) is meaningless. Always use the _per_million columns or compute them yourself.

Reporting noise

Many countries reported fewer cases on weekends (labs closed) creating a sawtooth pattern. Always use the _smoothed (7-day average) columns for trends.


Quick Exploration

import pandas as pd

df = pd.read_csv("owid-covid-data.csv", parse_dates=["date"])
print(df.shape)

# Filter to actual countries (drop aggregate rows)
countries = df[df["continent"].notna()].copy()

# Cases per million — fair comparison (latest available)
latest = countries.sort_values("date").groupby("location").last()
print(latest.nlargest(10, "total_cases_per_million")[["total_cases_per_million"]])

# Global daily cases
world = df[df["location"] == "World"]
print(world[["date", "new_cases_smoothed"]].tail())

← Business Problem · Next: Data Cleaning →