{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "### Data Management: Pandas\n", "\n", "[Pandas](http://pandas.pydata.org/) is an open source library providing high-performance, easy-to-use data structures and data analysis tools. Pandas is particularly suited to the analysis of *tabular* data, i.e. data that can go into a table. In other words, if you can imagine the data in an Excel spreadsheet, then Pandas is the tool for the job.\n", "\n", "- A fast and efficient DataFrame object for data manipulation with indexing\n", "- Tools for reading and writing data: CSV, Excel, SQL\n", "- Intelligent data alignment and integrated handling of missing data\n", "- Flexible reshaping and pivoting of data sets\n", "- Intelligent label-based slicing, indexing, and subsetting of large data sets\n", "- High performance aggregating, merging, joining or transforming data\n", "- Hierarchical indexing provides an intuitive way of working with high-dimensional data\n", "- Time series-functionality: date-based indexing, frequency conversion, moving windows, date shifting and lagging\n", "\n", ":::{.callout-note}\n", "Documentation for this package is available at https://pandas.pydata.org/docs/.\n", ":::\n", "\n", "To use Pandas, you typically import it with the alias `pd`" ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "execution": { "iopub.execute_input": "2026-01-19T18:20:41.471543Z", "iopub.status.busy": "2026-01-19T18:20:41.471299Z", "iopub.status.idle": "2026-01-19T18:20:42.044838Z", "shell.execute_reply": "2026-01-19T18:20:42.044038Z" } }, "outputs": [], "source": [ "import pandas as pd" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We will also import NumPy as it is often used alongside Pandas for numerical operations." ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "execution": { "iopub.execute_input": "2026-01-19T18:20:42.051413Z", "iopub.status.busy": "2026-01-19T18:20:42.050515Z", "iopub.status.idle": "2026-01-19T18:20:42.057892Z", "shell.execute_reply": "2026-01-19T18:20:42.057092Z" } }, "outputs": [], "source": [ "import numpy as np" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Pandas builds on two main data structures: `Series` and `DataFrames`. `Series` represent 1D arrays while `DataFrames` are 2D labeled arrays. The easiest way to think about both structures is to conceptualize `DataFrames` as containers of lower dimension data. That is, `DataFrames` columns are composed of `Series`, and each of the elements of a `Series` (i.e., the rows of the `DataFrame`) are individual scalar (numbers or strings) values. In plain words, `Series` are columns made of scalar elements and `DataFrames` are collections of `Series` that get an assigned label. \n", "All pandas data structures are value-mutable (i.e., we can change the values of elements and replace `DataFrames`) but some are not always size-mutable. The length of a Series cannot be changed, but, for example, columns can be inserted into a DataFrame.\n", "\n", "\n", "#### Pandas Series\n", "\n", "A `Series` is a one-dimensional labeled array capable of holding any data type (integers, strings, floating point numbers, Python objects, etc.). The axis labels are collectively referred to as the index. A `Series` can be created from a list, dictionary, or scalar value using the `pd.Series()` constructor. To create a `Series` from a list, you can do the following:" ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "execution": { "iopub.execute_input": "2026-01-19T18:20:42.061414Z", "iopub.status.busy": "2026-01-19T18:20:42.061089Z", "iopub.status.idle": "2026-01-19T18:20:42.066621Z", "shell.execute_reply": "2026-01-19T18:20:42.065944Z" } }, "outputs": [], "source": [ "data = [10, 20, 30, 40, 50]\n", "series = pd.Series(data)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "If you want to specify custom index labels, you can pass a list of labels to the `index` parameter:" ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "execution": { "iopub.execute_input": "2026-01-19T18:20:42.070621Z", "iopub.status.busy": "2026-01-19T18:20:42.069980Z", "iopub.status.idle": "2026-01-19T18:20:42.074083Z", "shell.execute_reply": "2026-01-19T18:20:42.073471Z" } }, "outputs": [], "source": [ "data = [10, 20, 30, 40, 50]\n", "labels = ['a', 'b', 'c', 'd', 'e']\n", "series = pd.Series(data, index=labels)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "You can additionally assign a name to the `Series` using the `name` parameter:" ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "execution": { "iopub.execute_input": "2026-01-19T18:20:42.076910Z", "iopub.status.busy": "2026-01-19T18:20:42.076470Z", "iopub.status.idle": "2026-01-19T18:20:42.081140Z", "shell.execute_reply": "2026-01-19T18:20:42.080065Z" } }, "outputs": [], "source": [ "data = [10, 20, 30, 40, 50]\n", "labels = ['a', 'b', 'c', 'd', 'e']\n", "series = pd.Series(data, index=labels, name='My Series')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "These functions work the same way when creating a `Series` from a NumPy array. When creating a `Series` from a dictionary, the keys of the dictionary become the index labels, and the values become the data:" ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "execution": { "iopub.execute_input": "2026-01-19T18:20:42.084351Z", "iopub.status.busy": "2026-01-19T18:20:42.084034Z", "iopub.status.idle": "2026-01-19T18:20:42.088595Z", "shell.execute_reply": "2026-01-19T18:20:42.087670Z" } }, "outputs": [], "source": [ "data = {'a': 10, 'b': 20, 'c': 30}\n", "series = pd.Series(data)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "You can access elements in a `Series` using their index labels or integer positions. For example, to access the element with label 'b':" ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "execution": { "iopub.execute_input": "2026-01-19T18:20:42.092065Z", "iopub.status.busy": "2026-01-19T18:20:42.091767Z", "iopub.status.idle": "2026-01-19T18:20:42.096737Z", "shell.execute_reply": "2026-01-19T18:20:42.095579Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Value at index 'b': 20\n" ] } ], "source": [ "value = series['b']\n", "print(\"Value at index 'b':\", value)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "If you want to access elements by their integer position, you can use the `iloc` attribute:" ] }, { "cell_type": "code", "execution_count": 8, "metadata": { "execution": { "iopub.execute_input": "2026-01-19T18:20:42.140491Z", "iopub.status.busy": "2026-01-19T18:20:42.140212Z", "iopub.status.idle": "2026-01-19T18:20:42.143816Z", "shell.execute_reply": "2026-01-19T18:20:42.143183Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Value at position 1: 20\n" ] } ], "source": [ "value = series.iloc[1] # Access the second element (index 1)\n", "print(\"Value at position 1:\", value)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Note that both label-based and positional indexing can be used interchangeably in many cases.\n", "\n", "`.loc` is used for label-based indexing, which means you access elements by their index labels:\n", "\n", "| Syntax | Description | Example | Result |\n", "|--------|-------------|---------|--------|\n", "| `series.loc[label]` | Single label access | `s.loc['b']` | Value at index 'b' |\n", "| `series.loc[label_list]` | Multiple labels | `s.loc[['a', 'c']]` | Series with values at 'a' and 'c' |\n", "| `series.loc[start:end]` | Slice by labels (inclusive) | `s.loc['a':'c']` | Series from 'a' to 'c' (inclusive) |\n", "| `series.loc[condition]` | Boolean indexing | `s.loc[s > 5]` | Values where condition is True |\n", "\n", "`.iloc` is used for positional indexing, which means you access elements by their integer position in the Series:\n", "\n", "| Syntax | Description | Example | Result |\n", "|--------|-------------|---------|--------|\n", "| `series.iloc[position]` | Single position access | `s.iloc[1]` | Value at position 1 |\n", "| `series.iloc[position_list]` | Multiple positions | `s.iloc[[0, 2]]` | Series with values at positions 0 and 2 |\n", "| `series.iloc[start:end]` | Slice by positions (exclusive end) | `s.iloc[1:3]` | Series from position 1 to 2 |\n", "| `series.iloc[negative_pos]` | Negative indexing | `s.iloc[-1]` | Value at last position |\n", "\n", "**Key Differences:**\n", "\n", "1. Indexing method:\n", " - `.loc` uses the actual index labels (strings, dates, etc.)\n", " - `.iloc` uses integer positions (0, 1, 2, ...)\n", "2. Slicing behavior:\n", " - `.loc` slicing is inclusive of both endpoints\n", " - `.iloc` slicing is exclusive of the end position\n", "\n", "\n", "You can retrieve all index labels and values of a `Series` using the `index` and `values` attributes, respectively:" ] }, { "cell_type": "code", "execution_count": 9, "metadata": { "execution": { "iopub.execute_input": "2026-01-19T18:20:42.146518Z", "iopub.status.busy": "2026-01-19T18:20:42.146258Z", "iopub.status.idle": "2026-01-19T18:20:42.150394Z", "shell.execute_reply": "2026-01-19T18:20:42.149933Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Index labels: Index(['a', 'b', 'c'], dtype='object')\n" ] } ], "source": [ "index_labels = series.index\n", "print(\"Index labels:\", index_labels)" ] }, { "cell_type": "code", "execution_count": 10, "metadata": { "execution": { "iopub.execute_input": "2026-01-19T18:20:42.152557Z", "iopub.status.busy": "2026-01-19T18:20:42.152317Z", "iopub.status.idle": "2026-01-19T18:20:42.155544Z", "shell.execute_reply": "2026-01-19T18:20:42.155107Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Values: [10 20 30]\n" ] } ], "source": [ "values = series.values\n", "print(\"Values:\", values)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "You can perform various operations on `Series`, such as arithmetic operations, aggregation functions, and filtering. For example, to add a scalar value to all elements in the `Series`:" ] }, { "cell_type": "code", "execution_count": 11, "metadata": { "execution": { "iopub.execute_input": "2026-01-19T18:20:42.157777Z", "iopub.status.busy": "2026-01-19T18:20:42.157567Z", "iopub.status.idle": "2026-01-19T18:20:42.161903Z", "shell.execute_reply": "2026-01-19T18:20:42.161296Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Series after adding 5:\n", " a 15\n", "b 25\n", "c 35\n", "dtype: int64\n" ] } ], "source": [ "new_series = series + 5\n", "print(\"Series after adding 5:\\n\", new_series)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "You can also filter the `Series` based on a condition:" ] }, { "cell_type": "code", "execution_count": 12, "metadata": { "execution": { "iopub.execute_input": "2026-01-19T18:20:42.164282Z", "iopub.status.busy": "2026-01-19T18:20:42.164052Z", "iopub.status.idle": "2026-01-19T18:20:42.167848Z", "shell.execute_reply": "2026-01-19T18:20:42.167349Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Filtered Series (values > 20):\n", " c 30\n", "dtype: int64\n" ] } ], "source": [ "filtered_series = series[series > 20]\n", "print(\"Filtered Series (values > 20):\\n\", filtered_series)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "They work and behave similarly to NumPy arrays in many ways but with additional functionality for handling missing data and labeled data.\n", "\n", "\n", "#### Pandas DataFrames\n", "\n", "Pandas Series are great for one-dimensional data, but in data science, we often work with two-dimensional data tables. This is where Pandas DataFrames come into play. A DataFrame is a two-dimensional labeled data structure with columns of potentially different types. You can think of it as a spreadsheet or SQL table, or a dictionary of Series objects.\n", "\n", "\n", "##### Creating DataFrames\n", "\n", "You can create a DataFrame from various data sources, such as dictionaries, lists of lists, or NumPy arrays. Here's an example of creating a DataFrame from a dictionary:" ] }, { "cell_type": "code", "execution_count": 13, "metadata": { "execution": { "iopub.execute_input": "2026-01-19T18:20:42.170419Z", "iopub.status.busy": "2026-01-19T18:20:42.170172Z", "iopub.status.idle": "2026-01-19T18:20:42.179114Z", "shell.execute_reply": "2026-01-19T18:20:42.178500Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "DataFrame:\n", " Age City\n", "Name \n", "Alba 30 New York\n", "Jesus 25 Los Angeles\n", "Yang 35 Chicago\n" ] } ], "source": [ "data = {\n", " 'Name': ['Alba', 'Jesus', 'Yang'],\n", " 'Age': [30, 25, 35],\n", " 'City': ['New York', 'Los Angeles', 'Chicago']\n", "}\n", "df = pd.DataFrame(data)\n", "df = df.set_index('Name') # Set 'Name' as the index\n", "print(\"DataFrame:\\n\", df)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "You can also create a DataFrame from a list of lists:" ] }, { "cell_type": "code", "execution_count": 14, "metadata": { "execution": { "iopub.execute_input": "2026-01-19T18:20:42.181819Z", "iopub.status.busy": "2026-01-19T18:20:42.181552Z", "iopub.status.idle": "2026-01-19T18:20:42.191463Z", "shell.execute_reply": "2026-01-19T18:20:42.190941Z" } }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
C1C2C3
R1123
R2456
R3789
\n", "
" ], "text/plain": [ " C1 C2 C3\n", "R1 1 2 3\n", "R2 4 5 6\n", "R3 7 8 9" ] }, "execution_count": 14, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Creating a DataFrame from a list of lists\n", "pd.DataFrame(\n", " data=[\n", " [1, 2, 3],\n", " [4, 5, 6],\n", " [7, 8, 9]\n", " ],\n", " index=[\"R1\", \"R2\", \"R3\"],\n", " columns=[\"C1\", \"C2\", \"C3\"]\n", ")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "There are several more ways to create DataFrames, including from CSV files, Excel files, SQL databases, and more. Most of the time, you'll be loading data from external sources rather than creating DataFrames from scratch.\n", "\n", "Indexing works similarly to Series, but now you have both row and column labels to consider. Here are some common ways to index and select data in a DataFrame:\n", "\n", "| Method | Description |\n", "|---|---|\n", "| `df[column_label]` or `df.column_label` or `df.loc[:, column_label]` | Access a single column by label (returns a Series) |\n", "| `df[[col1, col2]]` | Access multiple columns by label (returns a DataFrame) |\n", "| `df.loc[row_labels, column_labels]` | Access rows and columns by **label** (names) |\n", "| `df.iloc[row_positions, column_positions]` | Access rows and columns by **position** (integers) |\n", "| `df[boolean_condition]` | Filter rows based on a boolean condition |\n", "\n", "\n", "Consider the following DataFrame" ] }, { "cell_type": "code", "execution_count": 15, "metadata": { "execution": { "iopub.execute_input": "2026-01-19T18:20:42.194006Z", "iopub.status.busy": "2026-01-19T18:20:42.193715Z", "iopub.status.idle": "2026-01-19T18:20:42.205583Z", "shell.execute_reply": "2026-01-19T18:20:42.205073Z" } }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
areayeargdp_growthinflationpolicy_rateunemploymentfx_usd
AUSA20242.13.25.253.81.00
BEurozone20241.32.54.006.51.09
CJapan20240.71.0-0.102.6143.50
DUK20241.52.85.004.20.79
ECanada20241.82.24.755.11.36
FAustralia20242.02.64.354.01.51
\n", "
" ], "text/plain": [ " area year gdp_growth inflation policy_rate unemployment fx_usd\n", "A USA 2024 2.1 3.2 5.25 3.8 1.00\n", "B Eurozone 2024 1.3 2.5 4.00 6.5 1.09\n", "C Japan 2024 0.7 1.0 -0.10 2.6 143.50\n", "D UK 2024 1.5 2.8 5.00 4.2 0.79\n", "E Canada 2024 1.8 2.2 4.75 5.1 1.36\n", "F Australia 2024 2.0 2.6 4.35 4.0 1.51" ] }, "execution_count": 15, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df = pd.DataFrame(\n", " data={\n", " \"area\": [\"USA\", \"Eurozone\", \"Japan\", \"UK\", \"Canada\", \"Australia\"],\n", " \"year\": [2024, 2024, 2024, 2024, 2024, 2024],\n", " \"gdp_growth\": [2.1, 1.3, 0.7, 1.5, 1.8, 2.0], # in percent\n", " \"inflation\": [3.2, 2.5, 1.0, 2.8, 2.2, 2.6], # in percent\n", " \"policy_rate\": [5.25, 4.00, -0.10, 5.00, 4.75, 4.35], # in percent\n", " \"unemployment\": [3.8, 6.5, 2.6, 4.2, 5.1, 4.0], # in percent\n", " \"fx_usd\": [1.00, 1.09, 143.5, 0.79, 1.36, 1.51] # USD per unit of local currency\n", " },\n", " index=[\"A\", \"B\", \"C\", \"D\", \"E\", \"F\"]\n", ")\n", "df" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "First, we will set the \"areas\" column as the index of the DataFrame. This will allow us to access rows by area name. We can do this using the `set_index()` method. " ] }, { "cell_type": "code", "execution_count": 16, "metadata": { "execution": { "iopub.execute_input": "2026-01-19T18:20:42.208375Z", "iopub.status.busy": "2026-01-19T18:20:42.208103Z", "iopub.status.idle": "2026-01-19T18:20:42.211761Z", "shell.execute_reply": "2026-01-19T18:20:42.211068Z" } }, "outputs": [], "source": [ "df = df.set_index(\"area\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We could also do it in-place (modifying the original DataFrame directly)\n", "\n", "```python\n", "df.set_index(\"area\", inplace=True)\n", "```\n", "\n", "\n", "##### Inspecting DataFrames\n", "\n", "You can inspect the first few rows of a DataFrame using the `head()` method and the last few rows using the `tail()` method. By default, both methods display 5 rows, but you can specify a different number as an argument." ] }, { "cell_type": "code", "execution_count": 17, "metadata": { "execution": { "iopub.execute_input": "2026-01-19T18:20:42.214886Z", "iopub.status.busy": "2026-01-19T18:20:42.214595Z", "iopub.status.idle": "2026-01-19T18:20:42.225722Z", "shell.execute_reply": "2026-01-19T18:20:42.225195Z" } }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
yeargdp_growthinflationpolicy_rateunemploymentfx_usd
area
USA20242.13.25.253.81.00
Eurozone20241.32.54.006.51.09
Japan20240.71.0-0.102.6143.50
UK20241.52.85.004.20.79
Canada20241.82.24.755.11.36
\n", "
" ], "text/plain": [ " year gdp_growth inflation policy_rate unemployment fx_usd\n", "area \n", "USA 2024 2.1 3.2 5.25 3.8 1.00\n", "Eurozone 2024 1.3 2.5 4.00 6.5 1.09\n", "Japan 2024 0.7 1.0 -0.10 2.6 143.50\n", "UK 2024 1.5 2.8 5.00 4.2 0.79\n", "Canada 2024 1.8 2.2 4.75 5.1 1.36" ] }, "execution_count": 17, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df.head() # First 5 rows" ] }, { "cell_type": "code", "execution_count": 18, "metadata": { "execution": { "iopub.execute_input": "2026-01-19T18:20:42.228940Z", "iopub.status.busy": "2026-01-19T18:20:42.228545Z", "iopub.status.idle": "2026-01-19T18:20:42.237232Z", "shell.execute_reply": "2026-01-19T18:20:42.236697Z" } }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
yeargdp_growthinflationpolicy_rateunemploymentfx_usd
area
UK20241.52.85.004.20.79
Canada20241.82.24.755.11.36
Australia20242.02.64.354.01.51
\n", "
" ], "text/plain": [ " year gdp_growth inflation policy_rate unemployment fx_usd\n", "area \n", "UK 2024 1.5 2.8 5.00 4.2 0.79\n", "Canada 2024 1.8 2.2 4.75 5.1 1.36\n", "Australia 2024 2.0 2.6 4.35 4.0 1.51" ] }, "execution_count": 18, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df.tail(3) # Last 3 rows" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "You can get a summary of the DataFrame using the `info()` method, which provides information about the index, columns, data types, and memory usage." ] }, { "cell_type": "code", "execution_count": 19, "metadata": { "execution": { "iopub.execute_input": "2026-01-19T18:20:42.239925Z", "iopub.status.busy": "2026-01-19T18:20:42.239665Z", "iopub.status.idle": "2026-01-19T18:20:42.252706Z", "shell.execute_reply": "2026-01-19T18:20:42.251842Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "Index: 6 entries, USA to Australia\n", "Data columns (total 6 columns):\n", " # Column Non-Null Count Dtype \n", "--- ------ -------------- ----- \n", " 0 year 6 non-null int64 \n", " 1 gdp_growth 6 non-null float64\n", " 2 inflation 6 non-null float64\n", " 3 policy_rate 6 non-null float64\n", " 4 unemployment 6 non-null float64\n", " 5 fx_usd 6 non-null float64\n", "dtypes: float64(5), int64(1)\n", "memory usage: 336.0+ bytes\n" ] } ], "source": [ "df.info()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "You can get basic statistical details of the DataFrame using the `describe()` method, which provides measures like mean, standard deviation, min, max, and quartiles for numerical columns." ] }, { "cell_type": "code", "execution_count": 20, "metadata": { "execution": { "iopub.execute_input": "2026-01-19T18:20:42.256379Z", "iopub.status.busy": "2026-01-19T18:20:42.256016Z", "iopub.status.idle": "2026-01-19T18:20:42.277203Z", "shell.execute_reply": "2026-01-19T18:20:42.276533Z" } }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
yeargdp_growthinflationpolicy_rateunemploymentfx_usd
count6.06.0000006.0000006.0000006.0000006.000000
mean2024.01.5666672.3833333.8750004.36666724.875000
std0.00.5202560.7547631.9981871.31858558.114711
min2024.00.7000001.000000-0.1000002.6000000.790000
25%2024.01.3500002.2750004.0875003.8500001.022500
50%2024.01.6500002.5500004.5500004.1000001.225000
75%2024.01.9500002.7500004.9375004.8750001.472500
max2024.02.1000003.2000005.2500006.500000143.500000
\n", "
" ], "text/plain": [ " year gdp_growth inflation policy_rate unemployment fx_usd\n", "count 6.0 6.000000 6.000000 6.000000 6.000000 6.000000\n", "mean 2024.0 1.566667 2.383333 3.875000 4.366667 24.875000\n", "std 0.0 0.520256 0.754763 1.998187 1.318585 58.114711\n", "min 2024.0 0.700000 1.000000 -0.100000 2.600000 0.790000\n", "25% 2024.0 1.350000 2.275000 4.087500 3.850000 1.022500\n", "50% 2024.0 1.650000 2.550000 4.550000 4.100000 1.225000\n", "75% 2024.0 1.950000 2.750000 4.937500 4.875000 1.472500\n", "max 2024.0 2.100000 3.200000 5.250000 6.500000 143.500000" ] }, "execution_count": 20, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df.describe()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "##### Indexing and Selecting DataFrames\n", "\n", "We can get a single column as a Series using python's getitem syntax on the DataFrame object." ] }, { "cell_type": "code", "execution_count": 21, "metadata": { "execution": { "iopub.execute_input": "2026-01-19T18:20:42.281075Z", "iopub.status.busy": "2026-01-19T18:20:42.280725Z", "iopub.status.idle": "2026-01-19T18:20:42.286373Z", "shell.execute_reply": "2026-01-19T18:20:42.285466Z" } }, "outputs": [ { "data": { "text/plain": [ "area\n", "USA 3.2\n", "Eurozone 2.5\n", "Japan 1.0\n", "UK 2.8\n", "Canada 2.2\n", "Australia 2.6\n", "Name: inflation, dtype: float64" ] }, "execution_count": 21, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df['inflation'] # returns a series" ] }, { "cell_type": "code", "execution_count": 22, "metadata": { "execution": { "iopub.execute_input": "2026-01-19T18:20:42.289274Z", "iopub.status.busy": "2026-01-19T18:20:42.288970Z", "iopub.status.idle": "2026-01-19T18:20:42.293738Z", "shell.execute_reply": "2026-01-19T18:20:42.292838Z" } }, "outputs": [ { "data": { "text/plain": [ "pandas.core.series.Series" ] }, "execution_count": 22, "metadata": {}, "output_type": "execute_result" } ], "source": [ "type(df['inflation'])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "...or using attribute syntax." ] }, { "cell_type": "code", "execution_count": 23, "metadata": { "execution": { "iopub.execute_input": "2026-01-19T18:20:42.297731Z", "iopub.status.busy": "2026-01-19T18:20:42.297427Z", "iopub.status.idle": "2026-01-19T18:20:42.302757Z", "shell.execute_reply": "2026-01-19T18:20:42.302071Z" } }, "outputs": [ { "data": { "text/plain": [ "area\n", "USA 3.2\n", "Eurozone 2.5\n", "Japan 1.0\n", "UK 2.8\n", "Canada 2.2\n", "Australia 2.6\n", "Name: inflation, dtype: float64" ] }, "execution_count": 23, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df.inflation # returns a series" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "If we use a list of column names, we get a DataFrame back" ] }, { "cell_type": "code", "execution_count": 24, "metadata": { "execution": { "iopub.execute_input": "2026-01-19T18:20:42.305640Z", "iopub.status.busy": "2026-01-19T18:20:42.305358Z", "iopub.status.idle": "2026-01-19T18:20:42.313243Z", "shell.execute_reply": "2026-01-19T18:20:42.312511Z" } }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
inflation
area
USA3.2
Eurozone2.5
Japan1.0
UK2.8
Canada2.2
Australia2.6
\n", "
" ], "text/plain": [ " inflation\n", "area \n", "USA 3.2\n", "Eurozone 2.5\n", "Japan 1.0\n", "UK 2.8\n", "Canada 2.2\n", "Australia 2.6" ] }, "execution_count": 24, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df[['inflation']] # returns a DataFrame" ] }, { "cell_type": "code", "execution_count": 25, "metadata": { "execution": { "iopub.execute_input": "2026-01-19T18:20:42.316283Z", "iopub.status.busy": "2026-01-19T18:20:42.315896Z", "iopub.status.idle": "2026-01-19T18:20:42.321693Z", "shell.execute_reply": "2026-01-19T18:20:42.320980Z" } }, "outputs": [ { "data": { "text/plain": [ "pandas.core.frame.DataFrame" ] }, "execution_count": 25, "metadata": {}, "output_type": "execute_result" } ], "source": [ "type(df[['inflation']])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This is useful for selecting multiple columns at once." ] }, { "cell_type": "code", "execution_count": 26, "metadata": { "execution": { "iopub.execute_input": "2026-01-19T18:20:42.324815Z", "iopub.status.busy": "2026-01-19T18:20:42.324346Z", "iopub.status.idle": "2026-01-19T18:20:42.333919Z", "shell.execute_reply": "2026-01-19T18:20:42.333317Z" } }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
inflationunemployment
area
USA3.23.8
Eurozone2.56.5
Japan1.02.6
UK2.84.2
Canada2.25.1
Australia2.64.0
\n", "
" ], "text/plain": [ " inflation unemployment\n", "area \n", "USA 3.2 3.8\n", "Eurozone 2.5 6.5\n", "Japan 1.0 2.6\n", "UK 2.8 4.2\n", "Canada 2.2 5.1\n", "Australia 2.6 4.0" ] }, "execution_count": 26, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df[['inflation', 'unemployment']] # returns a dataframe with selected columns" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can use `.loc` to select rows and columns by label, and `.iloc` to select rows and columns by position.\n", "\n", "- **`.loc`** uses labels (names) for both rows and columns. The syntax is `df.loc[rows, columns]`. Both can be single labels, lists, or slices. Slices with `.loc` are **inclusive** of the end.\n", "- **`.iloc`** uses integer positions (like Python lists). The syntax is `df.iloc[rows, columns]`. Slices with `.iloc` are **exclusive** of the end (like standard Python slicing).\n", "\n", "Suppose `df` looks like this:\n", "\n", "| - | name | age | city |\n", "|---|-------|-----|--------|\n", "| 0 | Alice | 23 | Madrid |\n", "| 1 | Bob | 34 | London |\n", "| 2 | Carol | 29 | Berlin |\n", "\n", "- `df['age']` or `df.age` -> Series with ages.\n", "- `df[['name', 'city']]` -> DataFrame with just name and city columns.\n", "- `df.loc[1, 'city']` -> `'London'` (row label 1, column 'city').\n", "- `df.loc[0:1, ['name', 'age']]` -> Rows 0 to 1, columns 'name' and 'age' (inclusive).\n", "- `df.iloc[0:2, 1:3]` -> Rows 0 to 1, columns 1 and 2 (note that row 2 and column 3 are not included).\n", "- `df[df['age'] > 25]` -> Rows where age is greater than 25.\n", "\n", "As indicated above, both `.loc` and `.iloc` can take single labels/positions, lists of labels/positions, or slices. Here are some additional tips:\n", "\n", "- Use `:` to select all rows or columns: \n", " - `df.loc[:, 'age']` (all rows, 'age' column).\n", " - `df.iloc[1, :]` (row 1, all columns).\n", "- Remember: `.loc` is label-based and **inclusive**; `.iloc` is position-based and **exclusive**." ] }, { "cell_type": "code", "execution_count": 27, "metadata": { "execution": { "iopub.execute_input": "2026-01-19T18:20:42.336798Z", "iopub.status.busy": "2026-01-19T18:20:42.336499Z", "iopub.status.idle": "2026-01-19T18:20:42.341334Z", "shell.execute_reply": "2026-01-19T18:20:42.340698Z" } }, "outputs": [ { "data": { "text/plain": [ "np.float64(1.5)" ] }, "execution_count": 27, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df.loc[\"UK\",\"gdp_growth\"] # get the value in row \"UK\" and column \"gdp_growth\"" ] }, { "cell_type": "code", "execution_count": 28, "metadata": { "execution": { "iopub.execute_input": "2026-01-19T18:20:42.344155Z", "iopub.status.busy": "2026-01-19T18:20:42.343706Z", "iopub.status.idle": "2026-01-19T18:20:42.348660Z", "shell.execute_reply": "2026-01-19T18:20:42.347822Z" } }, "outputs": [ { "data": { "text/plain": [ "np.float64(1.5)" ] }, "execution_count": 28, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df.iloc[3,1] # get the value in row 3 and column 1 (recall: python uses zero-based index)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "You can also get subsets of rows and columns using slices or lists" ] }, { "cell_type": "code", "execution_count": 29, "metadata": { "execution": { "iopub.execute_input": "2026-01-19T18:20:42.351624Z", "iopub.status.busy": "2026-01-19T18:20:42.351339Z", "iopub.status.idle": "2026-01-19T18:20:42.362478Z", "shell.execute_reply": "2026-01-19T18:20:42.361794Z" } }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
policy_ratefx_usd
area
USA5.251.00
Eurozone4.001.09
Japan-0.10143.50
UK5.000.79
\n", "
" ], "text/plain": [ " policy_rate fx_usd\n", "area \n", "USA 5.25 1.00\n", "Eurozone 4.00 1.09\n", "Japan -0.10 143.50\n", "UK 5.00 0.79" ] }, "execution_count": 29, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df.loc[\"USA\":\"UK\",[\"policy_rate\", \"fx_usd\"]] # Subset rows from \"USA\" to \"UK\" and columns \"policy_rate\" and \"fx_usd\"" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can filter rows based on a boolean condition." ] }, { "cell_type": "code", "execution_count": 30, "metadata": { "execution": { "iopub.execute_input": "2026-01-19T18:20:42.365300Z", "iopub.status.busy": "2026-01-19T18:20:42.365007Z", "iopub.status.idle": "2026-01-19T18:20:42.374976Z", "shell.execute_reply": "2026-01-19T18:20:42.374375Z" } }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
yeargdp_growthinflationpolicy_rateunemploymentfx_usd
area
Eurozone20241.32.54.006.51.09
Canada20241.82.24.755.11.36
\n", "
" ], "text/plain": [ " year gdp_growth inflation policy_rate unemployment fx_usd\n", "area \n", "Eurozone 2024 1.3 2.5 4.00 6.5 1.09\n", "Canada 2024 1.8 2.2 4.75 5.1 1.36" ] }, "execution_count": 30, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df[df['unemployment'] > 5.0] # returns a dataframe with rows where unemployment is greater than 5.0" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "To filter rows in a DataFrame based on multiple conditions, you can use logical operators:\n", "\n", "| Operator | Symbol | Meaning | General Pattern |\n", "|----------|--------|-----------------------------------------|----------------------------------------|\n", "| AND | `&` | All conditions must be true | `df[(condition1) & (condition2)]` |\n", "| OR | `\\|` | At least one condition must be true | `df[(condition1) \\| (condition2)]` |\n", "| NOT | `~` | Negates a condition (condition is false)| `df[~(condition)]` |\n", "\n", "\n", "You can combine these operators to build more complex filters as needed. For example\n", "\n", ":::{python}\n", "`df[(condition1 & condition2) | (~condition3 & condition4)]`\n", ":::\n", "\n", "To reduce the likelihood of mistakes, always enclose each condition in parentheses to ensure correct evaluation.\n", "\n", "The following example filters the DataFrame to include only rows where the `fx_usd` is less than 1.0 **and** the `inflation` is greater than 2.0:" ] }, { "cell_type": "code", "execution_count": 31, "metadata": { "execution": { "iopub.execute_input": "2026-01-19T18:20:42.377641Z", "iopub.status.busy": "2026-01-19T18:20:42.377357Z", "iopub.status.idle": "2026-01-19T18:20:42.387319Z", "shell.execute_reply": "2026-01-19T18:20:42.386513Z" } }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
yeargdp_growthinflationpolicy_rateunemploymentfx_usd
area
UK20241.52.85.04.20.79
\n", "
" ], "text/plain": [ " year gdp_growth inflation policy_rate unemployment fx_usd\n", "area \n", "UK 2024 1.5 2.8 5.0 4.2 0.79" ] }, "execution_count": 31, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df[(df['fx_usd'] < 1.0) & (df[\"inflation\"] > 2.0)]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "An alternative to boolean indexing is the `query()` method, which allows you to filter rows using a string expression. This can be more readable, especially for complex conditions:" ] }, { "cell_type": "code", "execution_count": 32, "metadata": { "execution": { "iopub.execute_input": "2026-01-19T18:20:42.390517Z", "iopub.status.busy": "2026-01-19T18:20:42.390229Z", "iopub.status.idle": "2026-01-19T18:20:42.402190Z", "shell.execute_reply": "2026-01-19T18:20:42.401646Z" } }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
yeargdp_growthinflationpolicy_rateunemploymentfx_usd
area
UK20241.52.85.04.20.79
\n", "
" ], "text/plain": [ " year gdp_growth inflation policy_rate unemployment fx_usd\n", "area \n", "UK 2024 1.5 2.8 5.0 4.2 0.79" ] }, "execution_count": 32, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df.query(\"fx_usd < 1.0 and inflation > 2.0\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The `query()` method supports standard comparison operators (`<`, `>`, `==`, `!=`, `<=`, `>=`) and logical operators (`and`, `or`, `not`). You can also reference variables from the local environment using the `@` prefix:" ] }, { "cell_type": "code", "execution_count": 33, "metadata": { "execution": { "iopub.execute_input": "2026-01-19T18:20:42.404641Z", "iopub.status.busy": "2026-01-19T18:20:42.404400Z", "iopub.status.idle": "2026-01-19T18:20:42.415273Z", "shell.execute_reply": "2026-01-19T18:20:42.414763Z" } }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
yeargdp_growthinflationpolicy_rateunemploymentfx_usd
area
USA20242.13.25.253.81.00
Eurozone20241.32.54.006.51.09
UK20241.52.85.004.20.79
Canada20241.82.24.755.11.36
Australia20242.02.64.354.01.51
\n", "
" ], "text/plain": [ " year gdp_growth inflation policy_rate unemployment fx_usd\n", "area \n", "USA 2024 2.1 3.2 5.25 3.8 1.00\n", "Eurozone 2024 1.3 2.5 4.00 6.5 1.09\n", "UK 2024 1.5 2.8 5.00 4.2 0.79\n", "Canada 2024 1.8 2.2 4.75 5.1 1.36\n", "Australia 2024 2.0 2.6 4.35 4.0 1.51" ] }, "execution_count": 33, "metadata": {}, "output_type": "execute_result" } ], "source": [ "threshold = 2.0\n", "df.query(\"inflation > @threshold\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "##### DataFrame Operations\n", "\n", "There are many operations you can perform on DataFrames. Here are some common ones:\n", "\n", "Adding Columns:\n", "\n", "| Method | Code Pattern (Abstraction) | Notes |\n", "|----------------|------------------------------------------|--------------------------------------------|\n", "| Direct assign | `df[new_col] = values` | Adds or overwrites a column |\n", "| `assign()` | `df.assign(new_col=values)` | Adds a new column (returns a new DataFrame) |\n", "| `insert()` | `df.insert(loc, new_col, values)` | Adds at specific position |\n", "| Multiple cols | `df[[col1, col2]] = values` | Assign multiple columns at once |\n", "\n", "\n", "Adding Rows:\n", "\n", "| Method | Code Pattern (Abstraction) | Notes |\n", "|-------------|--------------------------------------|-----------------------------------------------|\n", "| `loc` | `df.loc[new_label] = values` | Adds or overwrites a row by index label |\n", "| `iloc` | `df.iloc[position] = values` | Overwrites a row at a specific integer position (does not add a new row) |\n", "| `concat()` | `df = pd.concat([df, new_rows_df])` | Adds one or more new rows from another DataFrame |\n", "\n", "\n", "For example, to add a new column that approximates real GDP growth (i.e., nominal GDP growth minus inflation):" ] }, { "cell_type": "code", "execution_count": 34, "metadata": { "execution": { "iopub.execute_input": "2026-01-19T18:20:42.417563Z", "iopub.status.busy": "2026-01-19T18:20:42.417335Z", "iopub.status.idle": "2026-01-19T18:20:42.428570Z", "shell.execute_reply": "2026-01-19T18:20:42.427888Z" } }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
yeargdp_growthinflationpolicy_rateunemploymentfx_usdreal_gdp_growthavg_weather
area
USA20242.13.25.253.81.00-1.120.5
Eurozone20241.32.54.006.51.09-1.218.0
Japan20240.71.0-0.102.6143.50-0.315.0
UK20241.52.85.004.20.79-1.312.5
Canada20241.82.24.755.11.36-0.410.0
Australia20242.02.64.354.01.51-0.622.0
\n", "
" ], "text/plain": [ " year gdp_growth inflation policy_rate unemployment fx_usd \\\n", "area \n", "USA 2024 2.1 3.2 5.25 3.8 1.00 \n", "Eurozone 2024 1.3 2.5 4.00 6.5 1.09 \n", "Japan 2024 0.7 1.0 -0.10 2.6 143.50 \n", "UK 2024 1.5 2.8 5.00 4.2 0.79 \n", "Canada 2024 1.8 2.2 4.75 5.1 1.36 \n", "Australia 2024 2.0 2.6 4.35 4.0 1.51 \n", "\n", " real_gdp_growth avg_weather \n", "area \n", "USA -1.1 20.5 \n", "Eurozone -1.2 18.0 \n", "Japan -0.3 15.0 \n", "UK -1.3 12.5 \n", "Canada -0.4 10.0 \n", "Australia -0.6 22.0 " ] }, "execution_count": 34, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df[\"real_gdp_growth\"] = df.gdp_growth - df.inflation # Create a new column as the difference between gdp_growth and inflation\n", "df[\"avg_weather\"] = [20.5, 18.0, 15.0, 12.5, 10.0, 22.0] # Add a new column with average weather data\n", "df" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Using `assign()`, we can do the same without modifying the original DataFrame (note that `assign()` returns a new DataFrame):" ] }, { "cell_type": "code", "execution_count": 35, "metadata": { "execution": { "iopub.execute_input": "2026-01-19T18:20:42.430997Z", "iopub.status.busy": "2026-01-19T18:20:42.430774Z", "iopub.status.idle": "2026-01-19T18:20:42.442121Z", "shell.execute_reply": "2026-01-19T18:20:42.441570Z" } }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
yeargdp_growthinflationpolicy_rateunemploymentfx_usdavg_weatherreal_gdp_growth
area
USA20242.13.25.253.81.0020.5-1.1
Eurozone20241.32.54.006.51.0918.0-1.2
Japan20240.71.0-0.102.6143.5015.0-0.3
UK20241.52.85.004.20.7912.5-1.3
Canada20241.82.24.755.11.3610.0-0.4
Australia20242.02.64.354.01.5122.0-0.6
\n", "
" ], "text/plain": [ " year gdp_growth inflation policy_rate unemployment fx_usd \\\n", "area \n", "USA 2024 2.1 3.2 5.25 3.8 1.00 \n", "Eurozone 2024 1.3 2.5 4.00 6.5 1.09 \n", "Japan 2024 0.7 1.0 -0.10 2.6 143.50 \n", "UK 2024 1.5 2.8 5.00 4.2 0.79 \n", "Canada 2024 1.8 2.2 4.75 5.1 1.36 \n", "Australia 2024 2.0 2.6 4.35 4.0 1.51 \n", "\n", " avg_weather real_gdp_growth \n", "area \n", "USA 20.5 -1.1 \n", "Eurozone 18.0 -1.2 \n", "Japan 15.0 -0.3 \n", "UK 12.5 -1.3 \n", "Canada 10.0 -0.4 \n", "Australia 22.0 -0.6 " ] }, "execution_count": 35, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df = df.drop(columns=[\"real_gdp_growth\"]) # Remove previously added column\n", "df_new = df.assign(real_gdp_growth=df.gdp_growth - df.inflation)\n", "df_new" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Using `insert()`, we can add a new column at a specific position. For example, to insert a `gdp_per_capita` column as the second column (index 1):" ] }, { "cell_type": "code", "execution_count": 36, "metadata": { "execution": { "iopub.execute_input": "2026-01-19T18:20:42.444406Z", "iopub.status.busy": "2026-01-19T18:20:42.444170Z", "iopub.status.idle": "2026-01-19T18:20:42.455320Z", "shell.execute_reply": "2026-01-19T18:20:42.454829Z" } }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
yeargdp_per_capitagdp_growthinflationpolicy_rateunemploymentfx_usdavg_weather
area
USA202460000.02.13.25.253.81.0020.5
Eurozone2024NaN1.32.54.006.51.0918.0
Japan202440000.00.71.0-0.102.6143.5015.0
UK2024NaN1.52.85.004.20.7912.5
Canada202455000.01.82.24.755.11.3610.0
Australia202470000.02.02.64.354.01.5122.0
\n", "
" ], "text/plain": [ " year gdp_per_capita gdp_growth inflation policy_rate \\\n", "area \n", "USA 2024 60000.0 2.1 3.2 5.25 \n", "Eurozone 2024 NaN 1.3 2.5 4.00 \n", "Japan 2024 40000.0 0.7 1.0 -0.10 \n", "UK 2024 NaN 1.5 2.8 5.00 \n", "Canada 2024 55000.0 1.8 2.2 4.75 \n", "Australia 2024 70000.0 2.0 2.6 4.35 \n", "\n", " unemployment fx_usd avg_weather \n", "area \n", "USA 3.8 1.00 20.5 \n", "Eurozone 6.5 1.09 18.0 \n", "Japan 2.6 143.50 15.0 \n", "UK 4.2 0.79 12.5 \n", "Canada 5.1 1.36 10.0 \n", "Australia 4.0 1.51 22.0 " ] }, "execution_count": 36, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df.insert(\n", " loc=1, # Insert at the second position (0-based index)\n", " column='gdp_per_capita', # Name of the new column\n", " value=[60000, np.nan, 40000, np.nan, 55000, 70000] # Values for the new column\n", ")\n", "df" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Deleting data:\n", "\n", "| What to Remove | Method/Option | Code Pattern (Abstraction) | Notes |\n", "|------------------------|----------------------|------------------------------------------------------------|---------------------------------------|\n", "| Columns by label | `drop()` | `df.drop([col1, col2, ...], axis=1)` | Returns new DataFrame |\n", "| Columns by label (in-place) | `drop()` | `df.drop([col1, col2, ...], axis=1, inplace=True)` | Modifies original DataFrame |\n", "| Columns by position | `drop()` | `df.drop(df.columns[[pos1, pos2, ...]], axis=1)` | Use integer positions |\n", "| Columns with missing values | `dropna()` | `df.dropna(axis=1)` | Removes columns with any missing |\n", "| Rows by label | `drop()` | `df.drop([row1, row2, ...], axis=0)` | Returns new DataFrame |\n", "| Rows by label (in-place) | `drop()` | `df.drop([row1, row2, ...], axis=0, inplace=True)` | Modifies original DataFrame |\n", "| Rows by position | `drop()` | `df.drop(df.index[[pos1, pos2, ...]], axis=0)` | Use integer positions |\n", "| Rows with missing values | `dropna()` | `df.dropna(axis=0)` | Removes rows with any missing |\n", "| Duplicate rows | `drop_duplicates()` | `df.drop_duplicates()` | Removes duplicate rows |\n", "\n", "\n", "For example, to remove the `avg_weather` column we just added" ] }, { "cell_type": "code", "execution_count": 37, "metadata": { "execution": { "iopub.execute_input": "2026-01-19T18:20:42.457642Z", "iopub.status.busy": "2026-01-19T18:20:42.457419Z", "iopub.status.idle": "2026-01-19T18:20:42.467376Z", "shell.execute_reply": "2026-01-19T18:20:42.466871Z" } }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
yeargdp_per_capitagdp_growthinflationpolicy_rateunemploymentfx_usd
area
USA202460000.02.13.25.253.81.00
Eurozone2024NaN1.32.54.006.51.09
Japan202440000.00.71.0-0.102.6143.50
UK2024NaN1.52.85.004.20.79
Canada202455000.01.82.24.755.11.36
Australia202470000.02.02.64.354.01.51
\n", "
" ], "text/plain": [ " year gdp_per_capita gdp_growth inflation policy_rate \\\n", "area \n", "USA 2024 60000.0 2.1 3.2 5.25 \n", "Eurozone 2024 NaN 1.3 2.5 4.00 \n", "Japan 2024 40000.0 0.7 1.0 -0.10 \n", "UK 2024 NaN 1.5 2.8 5.00 \n", "Canada 2024 55000.0 1.8 2.2 4.75 \n", "Australia 2024 70000.0 2.0 2.6 4.35 \n", "\n", " unemployment fx_usd \n", "area \n", "USA 3.8 1.00 \n", "Eurozone 6.5 1.09 \n", "Japan 2.6 143.50 \n", "UK 4.2 0.79 \n", "Canada 5.1 1.36 \n", "Australia 4.0 1.51 " ] }, "execution_count": 37, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df.drop(\"avg_weather\", axis=1)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can also drop columns with NaN values" ] }, { "cell_type": "code", "execution_count": 38, "metadata": { "execution": { "iopub.execute_input": "2026-01-19T18:20:42.469921Z", "iopub.status.busy": "2026-01-19T18:20:42.469668Z", "iopub.status.idle": "2026-01-19T18:20:42.480315Z", "shell.execute_reply": "2026-01-19T18:20:42.479636Z" } }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
yeargdp_growthinflationpolicy_rateunemploymentfx_usdavg_weather
area
USA20242.13.25.253.81.0020.5
Eurozone20241.32.54.006.51.0918.0
Japan20240.71.0-0.102.6143.5015.0
UK20241.52.85.004.20.7912.5
Canada20241.82.24.755.11.3610.0
Australia20242.02.64.354.01.5122.0
\n", "
" ], "text/plain": [ " year gdp_growth inflation policy_rate unemployment fx_usd \\\n", "area \n", "USA 2024 2.1 3.2 5.25 3.8 1.00 \n", "Eurozone 2024 1.3 2.5 4.00 6.5 1.09 \n", "Japan 2024 0.7 1.0 -0.10 2.6 143.50 \n", "UK 2024 1.5 2.8 5.00 4.2 0.79 \n", "Canada 2024 1.8 2.2 4.75 5.1 1.36 \n", "Australia 2024 2.0 2.6 4.35 4.0 1.51 \n", "\n", " avg_weather \n", "area \n", "USA 20.5 \n", "Eurozone 18.0 \n", "Japan 15.0 \n", "UK 12.5 \n", "Canada 10.0 \n", "Australia 22.0 " ] }, "execution_count": 38, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df.dropna(axis=1) # Drops columns with any NaN values" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Or fill it up with default \"fallback\" data:" ] }, { "cell_type": "code", "execution_count": 39, "metadata": { "execution": { "iopub.execute_input": "2026-01-19T18:20:42.482849Z", "iopub.status.busy": "2026-01-19T18:20:42.482604Z", "iopub.status.idle": "2026-01-19T18:20:42.494553Z", "shell.execute_reply": "2026-01-19T18:20:42.493996Z" } }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
yeargdp_per_capitagdp_growthinflationpolicy_rateunemploymentfx_usdavg_weather
area
USA202460000.02.13.25.253.81.0020.5
Eurozone202457500.01.32.54.006.51.0918.0
Japan202440000.00.71.0-0.102.6143.5015.0
UK202457500.01.52.85.004.20.7912.5
Canada202455000.01.82.24.755.11.3610.0
Australia202470000.02.02.64.354.01.5122.0
\n", "
" ], "text/plain": [ " year gdp_per_capita gdp_growth inflation policy_rate \\\n", "area \n", "USA 2024 60000.0 2.1 3.2 5.25 \n", "Eurozone 2024 57500.0 1.3 2.5 4.00 \n", "Japan 2024 40000.0 0.7 1.0 -0.10 \n", "UK 2024 57500.0 1.5 2.8 5.00 \n", "Canada 2024 55000.0 1.8 2.2 4.75 \n", "Australia 2024 70000.0 2.0 2.6 4.35 \n", "\n", " unemployment fx_usd avg_weather \n", "area \n", "USA 3.8 1.00 20.5 \n", "Eurozone 6.5 1.09 18.0 \n", "Japan 2.6 143.50 15.0 \n", "UK 4.2 0.79 12.5 \n", "Canada 5.1 1.36 10.0 \n", "Australia 4.0 1.51 22.0 " ] }, "execution_count": 39, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df.fillna(df.gdp_per_capita.median()) # Fills NaN values with the median of the gdp_per_capita column" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Note that both `drop()` and `fillna()` return a new DataFrame by default. Thus, when we access `df` again, we will see that it still contains the `avg_weather` column and any NaN values. " ] }, { "cell_type": "code", "execution_count": 40, "metadata": { "execution": { "iopub.execute_input": "2026-01-19T18:20:42.496945Z", "iopub.status.busy": "2026-01-19T18:20:42.496716Z", "iopub.status.idle": "2026-01-19T18:20:42.506719Z", "shell.execute_reply": "2026-01-19T18:20:42.506197Z" } }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
yeargdp_per_capitagdp_growthinflationpolicy_rateunemploymentfx_usdavg_weather
area
USA202460000.02.13.25.253.81.0020.5
Eurozone2024NaN1.32.54.006.51.0918.0
Japan202440000.00.71.0-0.102.6143.5015.0
UK2024NaN1.52.85.004.20.7912.5
Canada202455000.01.82.24.755.11.3610.0
Australia202470000.02.02.64.354.01.5122.0
\n", "
" ], "text/plain": [ " year gdp_per_capita gdp_growth inflation policy_rate \\\n", "area \n", "USA 2024 60000.0 2.1 3.2 5.25 \n", "Eurozone 2024 NaN 1.3 2.5 4.00 \n", "Japan 2024 40000.0 0.7 1.0 -0.10 \n", "UK 2024 NaN 1.5 2.8 5.00 \n", "Canada 2024 55000.0 1.8 2.2 4.75 \n", "Australia 2024 70000.0 2.0 2.6 4.35 \n", "\n", " unemployment fx_usd avg_weather \n", "area \n", "USA 3.8 1.00 20.5 \n", "Eurozone 6.5 1.09 18.0 \n", "Japan 2.6 143.50 15.0 \n", "UK 4.2 0.79 12.5 \n", "Canada 5.1 1.36 10.0 \n", "Australia 4.0 1.51 22.0 " ] }, "execution_count": 40, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df # Original DataFrame remains unchanged" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can also sort the entries in dataframes, e.g. alphabetically by index or numerically by column values\n", "\n", "| What to Sort | Method/Option | Code Pattern (Abstraction) | Notes |\n", "|----------------------|----------------------|--------------------------------------------------|--------------------------------------------|\n", "| By column(s) | `sort_values()` | `df.sort_values(by=col)` | Sort by one column (ascending by default) |\n", "| By multiple columns | `sort_values()` | `df.sort_values(by=[col1, col2])` | Sort by several columns (priority order) |\n", "| By column(s), descending | `sort_values()` | `df.sort_values(by=col, ascending=False)` | Sort in descending order |\n", "| By multiple columns, custom order | `sort_values()` | `df.sort_values(by=[col1, col2], ascending=[True, False])` | Custom order for each column |\n", "| By index | `sort_index()` | `df.sort_index()` | Sort by row index (ascending by default) |\n", "| By index, descending | `sort_index()` | `df.sort_index(ascending=False)` | Sort index in descending order |\n", "| By columns (column labels) | `sort_index()` | `df.sort_index(axis=1)` | Sort columns by their labels |\n", "| By columns, descending | `sort_index()` | `df.sort_index(axis=1, ascending=False)` | Sort columns in descending order |\n", "\n", "For example, to sort the DataFrame by `inflation` in descending order" ] }, { "cell_type": "code", "execution_count": 41, "metadata": { "execution": { "iopub.execute_input": "2026-01-19T18:20:42.509015Z", "iopub.status.busy": "2026-01-19T18:20:42.508792Z", "iopub.status.idle": "2026-01-19T18:20:42.519758Z", "shell.execute_reply": "2026-01-19T18:20:42.518856Z" } }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
yeargdp_per_capitagdp_growthinflationpolicy_rateunemploymentfx_usdavg_weather
area
USA202460000.02.13.25.253.81.0020.5
UK2024NaN1.52.85.004.20.7912.5
Australia202470000.02.02.64.354.01.5122.0
Eurozone2024NaN1.32.54.006.51.0918.0
Canada202455000.01.82.24.755.11.3610.0
Japan202440000.00.71.0-0.102.6143.5015.0
\n", "
" ], "text/plain": [ " year gdp_per_capita gdp_growth inflation policy_rate \\\n", "area \n", "USA 2024 60000.0 2.1 3.2 5.25 \n", "UK 2024 NaN 1.5 2.8 5.00 \n", "Australia 2024 70000.0 2.0 2.6 4.35 \n", "Eurozone 2024 NaN 1.3 2.5 4.00 \n", "Canada 2024 55000.0 1.8 2.2 4.75 \n", "Japan 2024 40000.0 0.7 1.0 -0.10 \n", "\n", " unemployment fx_usd avg_weather \n", "area \n", "USA 3.8 1.00 20.5 \n", "UK 4.2 0.79 12.5 \n", "Australia 4.0 1.51 22.0 \n", "Eurozone 6.5 1.09 18.0 \n", "Canada 5.1 1.36 10.0 \n", "Japan 2.6 143.50 15.0 " ] }, "execution_count": 41, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df.sort_values(by='inflation', ascending=False)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "To sort by multiple columns, e.g., first by `year` (ascending) and then by `gdp_growth` (descending):" ] }, { "cell_type": "code", "execution_count": 42, "metadata": { "execution": { "iopub.execute_input": "2026-01-19T18:20:42.522318Z", "iopub.status.busy": "2026-01-19T18:20:42.522083Z", "iopub.status.idle": "2026-01-19T18:20:42.534735Z", "shell.execute_reply": "2026-01-19T18:20:42.534235Z" } }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
yeargdp_per_capitagdp_growthinflationpolicy_rateunemploymentfx_usdavg_weather
area
USA202460000.02.13.25.253.81.0020.5
Australia202470000.02.02.64.354.01.5122.0
Canada202455000.01.82.24.755.11.3610.0
UK2024NaN1.52.85.004.20.7912.5
Eurozone2024NaN1.32.54.006.51.0918.0
Japan202440000.00.71.0-0.102.6143.5015.0
\n", "
" ], "text/plain": [ " year gdp_per_capita gdp_growth inflation policy_rate \\\n", "area \n", "USA 2024 60000.0 2.1 3.2 5.25 \n", "Australia 2024 70000.0 2.0 2.6 4.35 \n", "Canada 2024 55000.0 1.8 2.2 4.75 \n", "UK 2024 NaN 1.5 2.8 5.00 \n", "Eurozone 2024 NaN 1.3 2.5 4.00 \n", "Japan 2024 40000.0 0.7 1.0 -0.10 \n", "\n", " unemployment fx_usd avg_weather \n", "area \n", "USA 3.8 1.00 20.5 \n", "Australia 4.0 1.51 22.0 \n", "Canada 5.1 1.36 10.0 \n", "UK 4.2 0.79 12.5 \n", "Eurozone 6.5 1.09 18.0 \n", "Japan 2.6 143.50 15.0 " ] }, "execution_count": 42, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df.sort_values(by=['year', 'gdp_growth'], ascending=[True, False])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can also sort by index" ] }, { "cell_type": "code", "execution_count": 43, "metadata": { "execution": { "iopub.execute_input": "2026-01-19T18:20:42.537248Z", "iopub.status.busy": "2026-01-19T18:20:42.536999Z", "iopub.status.idle": "2026-01-19T18:20:42.548964Z", "shell.execute_reply": "2026-01-19T18:20:42.548263Z" } }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
yeargdp_per_capitagdp_growthinflationpolicy_rateunemploymentfx_usdavg_weather
area
Australia202470000.02.02.64.354.01.5122.0
Canada202455000.01.82.24.755.11.3610.0
Eurozone2024NaN1.32.54.006.51.0918.0
Japan202440000.00.71.0-0.102.6143.5015.0
UK2024NaN1.52.85.004.20.7912.5
USA202460000.02.13.25.253.81.0020.5
\n", "
" ], "text/plain": [ " year gdp_per_capita gdp_growth inflation policy_rate \\\n", "area \n", "Australia 2024 70000.0 2.0 2.6 4.35 \n", "Canada 2024 55000.0 1.8 2.2 4.75 \n", "Eurozone 2024 NaN 1.3 2.5 4.00 \n", "Japan 2024 40000.0 0.7 1.0 -0.10 \n", "UK 2024 NaN 1.5 2.8 5.00 \n", "USA 2024 60000.0 2.1 3.2 5.25 \n", "\n", " unemployment fx_usd avg_weather \n", "area \n", "Australia 4.0 1.51 22.0 \n", "Canada 5.1 1.36 10.0 \n", "Eurozone 6.5 1.09 18.0 \n", "Japan 2.6 143.50 15.0 \n", "UK 4.2 0.79 12.5 \n", "USA 3.8 1.00 20.5 " ] }, "execution_count": 43, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df.sort_index()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "or column names" ] }, { "cell_type": "code", "execution_count": 44, "metadata": { "execution": { "iopub.execute_input": "2026-01-19T18:20:42.551533Z", "iopub.status.busy": "2026-01-19T18:20:42.551304Z", "iopub.status.idle": "2026-01-19T18:20:42.562030Z", "shell.execute_reply": "2026-01-19T18:20:42.561425Z" } }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
avg_weatherfx_usdgdp_growthgdp_per_capitainflationpolicy_rateunemploymentyear
area
USA20.51.002.160000.03.25.253.82024
Eurozone18.01.091.3NaN2.54.006.52024
Japan15.0143.500.740000.01.0-0.102.62024
UK12.50.791.5NaN2.85.004.22024
Canada10.01.361.855000.02.24.755.12024
Australia22.01.512.070000.02.64.354.02024
\n", "
" ], "text/plain": [ " avg_weather fx_usd gdp_growth gdp_per_capita inflation \\\n", "area \n", "USA 20.5 1.00 2.1 60000.0 3.2 \n", "Eurozone 18.0 1.09 1.3 NaN 2.5 \n", "Japan 15.0 143.50 0.7 40000.0 1.0 \n", "UK 12.5 0.79 1.5 NaN 2.8 \n", "Canada 10.0 1.36 1.8 55000.0 2.2 \n", "Australia 22.0 1.51 2.0 70000.0 2.6 \n", "\n", " policy_rate unemployment year \n", "area \n", "USA 5.25 3.8 2024 \n", "Eurozone 4.00 6.5 2024 \n", "Japan -0.10 2.6 2024 \n", "UK 5.00 4.2 2024 \n", "Canada 4.75 5.1 2024 \n", "Australia 4.35 4.0 2024 " ] }, "execution_count": 44, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df.sort_index(axis=1)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Pandas supports a wide range of methods for merging different datasets. These are described extensively in the [documentation](https://pandas.pydata.org/pandas-docs/stable/merging.html). Here we just give a few examples.\n", "\n", "| Method | Function | Description | Key Parameters | Use Case |\n", "|--------|----------|-------------|----------------|----------|\n", "| **Inner Join** | `pd.merge(df1, df2, how='inner')` | Returns only rows with matching keys in both dataframes | `on`, `left_on`, `right_on` | When you only want records that exist in both datasets |\n", "| **Left Join** | `pd.merge(df1, df2, how='left')` | Returns all rows from left dataframe, matching rows from right | `on`, `left_on`, `right_on` | Keep all records from primary dataset, add matching info |\n", "| **Right Join** | `pd.merge(df1, df2, how='right')` | Returns all rows from right dataframe, matching rows from left | `on`, `left_on`, `right_on` | Keep all records from secondary dataset |\n", "| **Outer Join** | `pd.merge(df1, df2, how='outer')` | Returns all rows from both dataframes | `on`, `left_on`, `right_on` | When you want all records from both datasets |\n", "| **Cross Join** | `pd.merge(df1, df2, how='cross')` | Cartesian product of both dataframes | None required | Create all possible combinations |\n", "| **Concat Vertical** | `pd.concat([df1, df2])` | Stacks dataframes vertically (rows) | `axis=0`, `ignore_index` | Combine datasets with same columns |\n", "| **Concat Horizontal** | `pd.concat([df1, df2], axis=1)` | Joins dataframes horizontally (columns) | `axis=1`, `join` | Combine datasets with same index |\n", "| **Join Method** | `df1.join(df2)` | Left join based on index | `how`, `lsuffix`, `rsuffix` | Quick join on index when columns don't overlap |\n" ] }, { "cell_type": "code", "execution_count": 45, "metadata": { "execution": { "iopub.execute_input": "2026-01-19T18:20:42.564789Z", "iopub.status.busy": "2026-01-19T18:20:42.564383Z", "iopub.status.idle": "2026-01-19T18:20:42.571718Z", "shell.execute_reply": "2026-01-19T18:20:42.571170Z" } }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
exports_bnimports_bntrade_balance
area
USA16502407-757
Eurozone22002000200
Japan70564164
China33602601759
India323507-184
Brazil28121962
\n", "
" ], "text/plain": [ " exports_bn imports_bn trade_balance\n", "area \n", "USA 1650 2407 -757\n", "Eurozone 2200 2000 200\n", "Japan 705 641 64\n", "China 3360 2601 759\n", "India 323 507 -184\n", "Brazil 281 219 62" ] }, "execution_count": 45, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_trade = pd.DataFrame({\n", " \"area\": [\"USA\", \"Eurozone\", \"Japan\", \"China\", \"India\", \"Brazil\"],\n", " \"exports_bn\": [1650, 2200, 705, 3360, 323, 281],\n", " \"imports_bn\": [2407, 2000, 641, 2601, 507, 219],\n", " \"trade_balance\": [-757, 200, 64, 759, -184, 62]\n", "}).set_index(\"area\")\n", "df_trade" ] }, { "cell_type": "code", "execution_count": 46, "metadata": { "execution": { "iopub.execute_input": "2026-01-19T18:20:42.574041Z", "iopub.status.busy": "2026-01-19T18:20:42.573804Z", "iopub.status.idle": "2026-01-19T18:20:42.586493Z", "shell.execute_reply": "2026-01-19T18:20:42.585620Z" } }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
yeargdp_per_capitagdp_growthinflationpolicy_rateunemploymentfx_usdavg_weatherexports_bnimports_bntrade_balance
area
USA202460000.02.13.25.253.81.0020.516502407-757
Eurozone2024NaN1.32.54.006.51.0918.022002000200
Japan202440000.00.71.0-0.102.6143.5015.070564164
\n", "
" ], "text/plain": [ " year gdp_per_capita gdp_growth inflation policy_rate \\\n", "area \n", "USA 2024 60000.0 2.1 3.2 5.25 \n", "Eurozone 2024 NaN 1.3 2.5 4.00 \n", "Japan 2024 40000.0 0.7 1.0 -0.10 \n", "\n", " unemployment fx_usd avg_weather exports_bn imports_bn \\\n", "area \n", "USA 3.8 1.00 20.5 1650 2407 \n", "Eurozone 6.5 1.09 18.0 2200 2000 \n", "Japan 2.6 143.50 15.0 705 641 \n", "\n", " trade_balance \n", "area \n", "USA -757 \n", "Eurozone 200 \n", "Japan 64 " ] }, "execution_count": 46, "metadata": {}, "output_type": "execute_result" } ], "source": [ "inner_result = pd.merge(df, df_trade, how='inner', left_index=True, right_index=True)\n", "inner_result" ] }, { "cell_type": "code", "execution_count": 47, "metadata": { "execution": { "iopub.execute_input": "2026-01-19T18:20:42.590144Z", "iopub.status.busy": "2026-01-19T18:20:42.589875Z", "iopub.status.idle": "2026-01-19T18:20:42.606352Z", "shell.execute_reply": "2026-01-19T18:20:42.605681Z" } }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
yeargdp_per_capitagdp_growthinflationpolicy_rateunemploymentfx_usdavg_weatherexports_bnimports_bntrade_balance
area
USA202460000.02.13.25.253.81.0020.51650.02407.0-757.0
Eurozone2024NaN1.32.54.006.51.0918.02200.02000.0200.0
Japan202440000.00.71.0-0.102.6143.5015.0705.0641.064.0
UK2024NaN1.52.85.004.20.7912.5NaNNaNNaN
Canada202455000.01.82.24.755.11.3610.0NaNNaNNaN
Australia202470000.02.02.64.354.01.5122.0NaNNaNNaN
\n", "
" ], "text/plain": [ " year gdp_per_capita gdp_growth inflation policy_rate \\\n", "area \n", "USA 2024 60000.0 2.1 3.2 5.25 \n", "Eurozone 2024 NaN 1.3 2.5 4.00 \n", "Japan 2024 40000.0 0.7 1.0 -0.10 \n", "UK 2024 NaN 1.5 2.8 5.00 \n", "Canada 2024 55000.0 1.8 2.2 4.75 \n", "Australia 2024 70000.0 2.0 2.6 4.35 \n", "\n", " unemployment fx_usd avg_weather exports_bn imports_bn \\\n", "area \n", "USA 3.8 1.00 20.5 1650.0 2407.0 \n", "Eurozone 6.5 1.09 18.0 2200.0 2000.0 \n", "Japan 2.6 143.50 15.0 705.0 641.0 \n", "UK 4.2 0.79 12.5 NaN NaN \n", "Canada 5.1 1.36 10.0 NaN NaN \n", "Australia 4.0 1.51 22.0 NaN NaN \n", "\n", " trade_balance \n", "area \n", "USA -757.0 \n", "Eurozone 200.0 \n", "Japan 64.0 \n", "UK NaN \n", "Canada NaN \n", "Australia NaN " ] }, "execution_count": 47, "metadata": {}, "output_type": "execute_result" } ], "source": [ "left_result = pd.merge(df, df_trade, how='left', left_index=True, right_index=True)\n", "left_result" ] }, { "cell_type": "code", "execution_count": 48, "metadata": { "execution": { "iopub.execute_input": "2026-01-19T18:20:42.609211Z", "iopub.status.busy": "2026-01-19T18:20:42.608942Z", "iopub.status.idle": "2026-01-19T18:20:42.622135Z", "shell.execute_reply": "2026-01-19T18:20:42.621569Z" } }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
yeargdp_per_capitagdp_growthinflationpolicy_rateunemploymentfx_usdavg_weatherexports_bnimports_bntrade_balance
area
USA2024.060000.02.13.25.253.81.0020.516502407-757
Eurozone2024.0NaN1.32.54.006.51.0918.022002000200
Japan2024.040000.00.71.0-0.102.6143.5015.070564164
ChinaNaNNaNNaNNaNNaNNaNNaNNaN33602601759
IndiaNaNNaNNaNNaNNaNNaNNaNNaN323507-184
BrazilNaNNaNNaNNaNNaNNaNNaNNaN28121962
\n", "
" ], "text/plain": [ " year gdp_per_capita gdp_growth inflation policy_rate \\\n", "area \n", "USA 2024.0 60000.0 2.1 3.2 5.25 \n", "Eurozone 2024.0 NaN 1.3 2.5 4.00 \n", "Japan 2024.0 40000.0 0.7 1.0 -0.10 \n", "China NaN NaN NaN NaN NaN \n", "India NaN NaN NaN NaN NaN \n", "Brazil NaN NaN NaN NaN NaN \n", "\n", " unemployment fx_usd avg_weather exports_bn imports_bn \\\n", "area \n", "USA 3.8 1.00 20.5 1650 2407 \n", "Eurozone 6.5 1.09 18.0 2200 2000 \n", "Japan 2.6 143.50 15.0 705 641 \n", "China NaN NaN NaN 3360 2601 \n", "India NaN NaN NaN 323 507 \n", "Brazil NaN NaN NaN 281 219 \n", "\n", " trade_balance \n", "area \n", "USA -757 \n", "Eurozone 200 \n", "Japan 64 \n", "China 759 \n", "India -184 \n", "Brazil 62 " ] }, "execution_count": 48, "metadata": {}, "output_type": "execute_result" } ], "source": [ "right_result = pd.merge(df, df_trade, how='right', left_index=True, right_index=True)\n", "right_result" ] }, { "cell_type": "code", "execution_count": 49, "metadata": { "execution": { "iopub.execute_input": "2026-01-19T18:20:42.624492Z", "iopub.status.busy": "2026-01-19T18:20:42.624252Z", "iopub.status.idle": "2026-01-19T18:20:42.641678Z", "shell.execute_reply": "2026-01-19T18:20:42.641154Z" } }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
yeargdp_per_capitagdp_growthinflationpolicy_rateunemploymentfx_usdavg_weatherexports_bnimports_bntrade_balance
area
Australia2024.070000.02.02.64.354.01.5122.0NaNNaNNaN
BrazilNaNNaNNaNNaNNaNNaNNaNNaN281.0219.062.0
Canada2024.055000.01.82.24.755.11.3610.0NaNNaNNaN
ChinaNaNNaNNaNNaNNaNNaNNaNNaN3360.02601.0759.0
Eurozone2024.0NaN1.32.54.006.51.0918.02200.02000.0200.0
IndiaNaNNaNNaNNaNNaNNaNNaNNaN323.0507.0-184.0
Japan2024.040000.00.71.0-0.102.6143.5015.0705.0641.064.0
UK2024.0NaN1.52.85.004.20.7912.5NaNNaNNaN
USA2024.060000.02.13.25.253.81.0020.51650.02407.0-757.0
\n", "
" ], "text/plain": [ " year gdp_per_capita gdp_growth inflation policy_rate \\\n", "area \n", "Australia 2024.0 70000.0 2.0 2.6 4.35 \n", "Brazil NaN NaN NaN NaN NaN \n", "Canada 2024.0 55000.0 1.8 2.2 4.75 \n", "China NaN NaN NaN NaN NaN \n", "Eurozone 2024.0 NaN 1.3 2.5 4.00 \n", "India NaN NaN NaN NaN NaN \n", "Japan 2024.0 40000.0 0.7 1.0 -0.10 \n", "UK 2024.0 NaN 1.5 2.8 5.00 \n", "USA 2024.0 60000.0 2.1 3.2 5.25 \n", "\n", " unemployment fx_usd avg_weather exports_bn imports_bn \\\n", "area \n", "Australia 4.0 1.51 22.0 NaN NaN \n", "Brazil NaN NaN NaN 281.0 219.0 \n", "Canada 5.1 1.36 10.0 NaN NaN \n", "China NaN NaN NaN 3360.0 2601.0 \n", "Eurozone 6.5 1.09 18.0 2200.0 2000.0 \n", "India NaN NaN NaN 323.0 507.0 \n", "Japan 2.6 143.50 15.0 705.0 641.0 \n", "UK 4.2 0.79 12.5 NaN NaN \n", "USA 3.8 1.00 20.5 1650.0 2407.0 \n", "\n", " trade_balance \n", "area \n", "Australia NaN \n", "Brazil 62.0 \n", "Canada NaN \n", "China 759.0 \n", "Eurozone 200.0 \n", "India -184.0 \n", "Japan 64.0 \n", "UK NaN \n", "USA -757.0 " ] }, "execution_count": 49, "metadata": {}, "output_type": "execute_result" } ], "source": [ "outer_result = pd.merge(df, df_trade, how='outer', left_index=True, right_index=True)\n", "outer_result" ] }, { "cell_type": "code", "execution_count": 50, "metadata": { "execution": { "iopub.execute_input": "2026-01-19T18:20:42.644099Z", "iopub.status.busy": "2026-01-19T18:20:42.643844Z", "iopub.status.idle": "2026-01-19T18:20:42.660188Z", "shell.execute_reply": "2026-01-19T18:20:42.659568Z" } }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
yeargdp_per_capitagdp_growthinflationpolicy_rateunemploymentfx_usdavg_weatherexports_bnimports_bntrade_balance
area
Australia2024.070000.02.02.64.354.01.5122.0NaNNaNNaN
BrazilNaNNaNNaNNaNNaNNaNNaNNaN281.0219.062.0
Canada2024.055000.01.82.24.755.11.3610.0NaNNaNNaN
ChinaNaNNaNNaNNaNNaNNaNNaNNaN3360.02601.0759.0
Eurozone2024.0NaN1.32.54.006.51.0918.02200.02000.0200.0
IndiaNaNNaNNaNNaNNaNNaNNaNNaN323.0507.0-184.0
Japan2024.040000.00.71.0-0.102.6143.5015.0705.0641.064.0
UK2024.0NaN1.52.85.004.20.7912.5NaNNaNNaN
USA2024.060000.02.13.25.253.81.0020.51650.02407.0-757.0
\n", "
" ], "text/plain": [ " year gdp_per_capita gdp_growth inflation policy_rate \\\n", "area \n", "Australia 2024.0 70000.0 2.0 2.6 4.35 \n", "Brazil NaN NaN NaN NaN NaN \n", "Canada 2024.0 55000.0 1.8 2.2 4.75 \n", "China NaN NaN NaN NaN NaN \n", "Eurozone 2024.0 NaN 1.3 2.5 4.00 \n", "India NaN NaN NaN NaN NaN \n", "Japan 2024.0 40000.0 0.7 1.0 -0.10 \n", "UK 2024.0 NaN 1.5 2.8 5.00 \n", "USA 2024.0 60000.0 2.1 3.2 5.25 \n", "\n", " unemployment fx_usd avg_weather exports_bn imports_bn \\\n", "area \n", "Australia 4.0 1.51 22.0 NaN NaN \n", "Brazil NaN NaN NaN 281.0 219.0 \n", "Canada 5.1 1.36 10.0 NaN NaN \n", "China NaN NaN NaN 3360.0 2601.0 \n", "Eurozone 6.5 1.09 18.0 2200.0 2000.0 \n", "India NaN NaN NaN 323.0 507.0 \n", "Japan 2.6 143.50 15.0 705.0 641.0 \n", "UK 4.2 0.79 12.5 NaN NaN \n", "USA 3.8 1.00 20.5 1650.0 2407.0 \n", "\n", " trade_balance \n", "area \n", "Australia NaN \n", "Brazil 62.0 \n", "Canada NaN \n", "China 759.0 \n", "Eurozone 200.0 \n", "India -184.0 \n", "Japan 64.0 \n", "UK NaN \n", "USA -757.0 " ] }, "execution_count": 50, "metadata": {}, "output_type": "execute_result" } ], "source": [ "pd.concat([df, df_trade], axis=1).sort_index() # Concatenate along columns" ] }, { "cell_type": "code", "execution_count": 51, "metadata": { "execution": { "iopub.execute_input": "2026-01-19T18:20:42.663338Z", "iopub.status.busy": "2026-01-19T18:20:42.662999Z", "iopub.status.idle": "2026-01-19T18:20:42.686356Z", "shell.execute_reply": "2026-01-19T18:20:42.685735Z" } }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
yeargdp_per_capitagdp_growthinflationpolicy_rateunemploymentfx_usdavg_weatherexports_bnimports_bntrade_balance
area
USA2024.060000.02.13.25.253.81.0020.5NaNNaNNaN
Eurozone2024.0NaN1.32.54.006.51.0918.0NaNNaNNaN
Japan2024.040000.00.71.0-0.102.6143.5015.0NaNNaNNaN
UK2024.0NaN1.52.85.004.20.7912.5NaNNaNNaN
Canada2024.055000.01.82.24.755.11.3610.0NaNNaNNaN
Australia2024.070000.02.02.64.354.01.5122.0NaNNaNNaN
USANaNNaNNaNNaNNaNNaNNaNNaN1650.02407.0-757.0
EurozoneNaNNaNNaNNaNNaNNaNNaNNaN2200.02000.0200.0
JapanNaNNaNNaNNaNNaNNaNNaNNaN705.0641.064.0
ChinaNaNNaNNaNNaNNaNNaNNaNNaN3360.02601.0759.0
IndiaNaNNaNNaNNaNNaNNaNNaNNaN323.0507.0-184.0
BrazilNaNNaNNaNNaNNaNNaNNaNNaN281.0219.062.0
\n", "
" ], "text/plain": [ " year gdp_per_capita gdp_growth inflation policy_rate \\\n", "area \n", "USA 2024.0 60000.0 2.1 3.2 5.25 \n", "Eurozone 2024.0 NaN 1.3 2.5 4.00 \n", "Japan 2024.0 40000.0 0.7 1.0 -0.10 \n", "UK 2024.0 NaN 1.5 2.8 5.00 \n", "Canada 2024.0 55000.0 1.8 2.2 4.75 \n", "Australia 2024.0 70000.0 2.0 2.6 4.35 \n", "USA NaN NaN NaN NaN NaN \n", "Eurozone NaN NaN NaN NaN NaN \n", "Japan NaN NaN NaN NaN NaN \n", "China NaN NaN NaN NaN NaN \n", "India NaN NaN NaN NaN NaN \n", "Brazil NaN NaN NaN NaN NaN \n", "\n", " unemployment fx_usd avg_weather exports_bn imports_bn \\\n", "area \n", "USA 3.8 1.00 20.5 NaN NaN \n", "Eurozone 6.5 1.09 18.0 NaN NaN \n", "Japan 2.6 143.50 15.0 NaN NaN \n", "UK 4.2 0.79 12.5 NaN NaN \n", "Canada 5.1 1.36 10.0 NaN NaN \n", "Australia 4.0 1.51 22.0 NaN NaN \n", "USA NaN NaN NaN 1650.0 2407.0 \n", "Eurozone NaN NaN NaN 2200.0 2000.0 \n", "Japan NaN NaN NaN 705.0 641.0 \n", "China NaN NaN NaN 3360.0 2601.0 \n", "India NaN NaN NaN 323.0 507.0 \n", "Brazil NaN NaN NaN 281.0 219.0 \n", "\n", " trade_balance \n", "area \n", "USA NaN \n", "Eurozone NaN \n", "Japan NaN \n", "UK NaN \n", "Canada NaN \n", "Australia NaN \n", "USA -757.0 \n", "Eurozone 200.0 \n", "Japan 64.0 \n", "China 759.0 \n", "India -184.0 \n", "Brazil 62.0 " ] }, "execution_count": 51, "metadata": {}, "output_type": "execute_result" } ], "source": [ "pd.concat([df, df_trade], axis=0) # Concatenate along rows" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Sometimes it can be useful to apply a function to all values of a column/row. For instance, we might be interested in normalised inflation. We can do this using the `apply()` method. This method applies a function to each element in the Series or DataFrame." ] }, { "cell_type": "code", "execution_count": 52, "metadata": { "execution": { "iopub.execute_input": "2026-01-19T18:20:42.689857Z", "iopub.status.busy": "2026-01-19T18:20:42.689257Z", "iopub.status.idle": "2026-01-19T18:20:42.696733Z", "shell.execute_reply": "2026-01-19T18:20:42.696192Z" } }, "outputs": [ { "data": { "text/plain": [ "area\n", "USA 1.082018\n", "Eurozone 0.154574\n", "Japan -1.832806\n", "UK 0.552050\n", "Canada -0.242902\n", "Australia 0.287066\n", "Name: inflation, dtype: float64" ] }, "execution_count": 52, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df.inflation.apply(lambda x: (x - df.inflation.mean()) / df.inflation.std()) # Standardize the inflation column" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Sometimes it is necessary to rename columns or indices in a DataFrame. There are several ways to do this, depending on whether you want to rename all columns, specific columns, or apply a function to transform the names.\n", "\n", "| Method | Syntax | Use Case | Example |\n", "|--------|--------|----------|---------|\n", "| **Direct Assignment** | `df.columns = [list]` | Replace all column names at once | `df.columns = ['A', 'B', 'C']` |\n", "| **rename() with Dictionary** | `df.rename(columns={dict})` | Rename specific columns selectively | `df.rename(columns={'old': 'new'})` |\n", "| **rename() with inplace** | `df.rename(columns={dict}, inplace=True)` | Modify original DataFrame directly | `df.rename(columns={'old': 'new'}, inplace=True)` |\n", "| **rename() with Function** | `df.rename(columns=function)` | Apply transformation to all columns | `df.rename(columns=str.upper)` |\n", "| **String Methods** | `df.columns.str.method()` | Apply string operations to column names | `df.columns = df.columns.str.replace('_', ' ')` |\n", "| **Lambda Function** | `df.rename(columns=lambda x: expression)` | Custom transformations on column names | `df.rename(columns=lambda x: x.replace('old', 'new'))` |\n", "\n", "Key Parameters\n", "\n", "| Parameter | Description | Default | Example |\n", "|-----------|-------------|---------|---------|\n", "| `columns` | Dictionary or function for column mapping | `None` | `{'old_name': 'new_name'}` |\n", "| `inplace` | Modify DataFrame in place vs. return copy | `False` | `inplace=True` |\n", "| `errors` | How to handle missing keys | `'ignore'` | `errors='raise'` |\n" ] }, { "cell_type": "code", "execution_count": 53, "metadata": { "execution": { "iopub.execute_input": "2026-01-19T18:20:42.699301Z", "iopub.status.busy": "2026-01-19T18:20:42.698973Z", "iopub.status.idle": "2026-01-19T18:20:42.712647Z", "shell.execute_reply": "2026-01-19T18:20:42.712034Z" } }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
yeargdp_per_capita_($)gdp_growth_(%)inflation_rate_(%)policy_rate_(%)unemployment_rate_(%)fx_rate_($/X)avg_weather_(°C)
area
USA202460000.02.13.25.253.81.0020.5
Eurozone2024NaN1.32.54.006.51.0918.0
Japan202440000.00.71.0-0.102.6143.5015.0
UK2024NaN1.52.85.004.20.7912.5
Canada202455000.01.82.24.755.11.3610.0
Australia202470000.02.02.64.354.01.5122.0
\n", "
" ], "text/plain": [ " year gdp_per_capita_($) gdp_growth_(%) inflation_rate_(%) \\\n", "area \n", "USA 2024 60000.0 2.1 3.2 \n", "Eurozone 2024 NaN 1.3 2.5 \n", "Japan 2024 40000.0 0.7 1.0 \n", "UK 2024 NaN 1.5 2.8 \n", "Canada 2024 55000.0 1.8 2.2 \n", "Australia 2024 70000.0 2.0 2.6 \n", "\n", " policy_rate_(%) unemployment_rate_(%) fx_rate_($/X) \\\n", "area \n", "USA 5.25 3.8 1.00 \n", "Eurozone 4.00 6.5 1.09 \n", "Japan -0.10 2.6 143.50 \n", "UK 5.00 4.2 0.79 \n", "Canada 4.75 5.1 1.36 \n", "Australia 4.35 4.0 1.51 \n", "\n", " avg_weather_(°C) \n", "area \n", "USA 20.5 \n", "Eurozone 18.0 \n", "Japan 15.0 \n", "UK 12.5 \n", "Canada 10.0 \n", "Australia 22.0 " ] }, "execution_count": 53, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df1 = df.copy() # Create a copy of the DataFrame\n", "\n", "df1 = df1.rename(columns={\n", " \"gdp_growth\": \"gdp_growth_(%)\",\n", " \"gdp_per_capita\": \"gdp_per_capita_($)\", \n", " \"inflation\": \"inflation_rate_(%)\",\n", " \"policy_rate\": \"policy_rate_(%)\",\n", " \"unemployment\": \"unemployment_rate_(%)\",\n", " \"fx_usd\": \"fx_rate_($/X)\",\n", " \"avg_weather\": \"avg_weather_(°C)\",\n", " }) # Rename columns\n", "df1" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can also work directly with column names" ] }, { "cell_type": "code", "execution_count": 54, "metadata": { "execution": { "iopub.execute_input": "2026-01-19T18:20:42.716166Z", "iopub.status.busy": "2026-01-19T18:20:42.715828Z", "iopub.status.idle": "2026-01-19T18:20:42.728729Z", "shell.execute_reply": "2026-01-19T18:20:42.727911Z" } }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
yeargdp per capitagdp growthinflationpolicy rateunemploymentfx usdavg weather
area
USA202460000.02.13.25.253.81.0020.5
Eurozone2024NaN1.32.54.006.51.0918.0
Japan202440000.00.71.0-0.102.6143.5015.0
UK2024NaN1.52.85.004.20.7912.5
Canada202455000.01.82.24.755.11.3610.0
Australia202470000.02.02.64.354.01.5122.0
\n", "
" ], "text/plain": [ " year gdp per capita gdp growth inflation policy rate \\\n", "area \n", "USA 2024 60000.0 2.1 3.2 5.25 \n", "Eurozone 2024 NaN 1.3 2.5 4.00 \n", "Japan 2024 40000.0 0.7 1.0 -0.10 \n", "UK 2024 NaN 1.5 2.8 5.00 \n", "Canada 2024 55000.0 1.8 2.2 4.75 \n", "Australia 2024 70000.0 2.0 2.6 4.35 \n", "\n", " unemployment fx usd avg weather \n", "area \n", "USA 3.8 1.00 20.5 \n", "Eurozone 6.5 1.09 18.0 \n", "Japan 2.6 143.50 15.0 \n", "UK 4.2 0.79 12.5 \n", "Canada 5.1 1.36 10.0 \n", "Australia 4.0 1.51 22.0 " ] }, "execution_count": 54, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df1.columns = df.columns.str.replace('_', ' ')\n", "df1 " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "or the row names" ] }, { "cell_type": "code", "execution_count": 55, "metadata": { "execution": { "iopub.execute_input": "2026-01-19T18:20:42.731870Z", "iopub.status.busy": "2026-01-19T18:20:42.731601Z", "iopub.status.idle": "2026-01-19T18:20:42.742794Z", "shell.execute_reply": "2026-01-19T18:20:42.742198Z" } }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
YearGdp_per_capitaGdp_growthInflationPolicy_rateUnemploymentFx_usdAvg_weather
area
USA202460000.02.13.25.253.81.0020.5
EUROZONE2024NaN1.32.54.006.51.0918.0
JAPAN202440000.00.71.0-0.102.6143.5015.0
UK2024NaN1.52.85.004.20.7912.5
CANADA202455000.01.82.24.755.11.3610.0
AUSTRALIA202470000.02.02.64.354.01.5122.0
\n", "
" ], "text/plain": [ " Year Gdp_per_capita Gdp_growth Inflation Policy_rate \\\n", "area \n", "USA 2024 60000.0 2.1 3.2 5.25 \n", "EUROZONE 2024 NaN 1.3 2.5 4.00 \n", "JAPAN 2024 40000.0 0.7 1.0 -0.10 \n", "UK 2024 NaN 1.5 2.8 5.00 \n", "CANADA 2024 55000.0 1.8 2.2 4.75 \n", "AUSTRALIA 2024 70000.0 2.0 2.6 4.35 \n", "\n", " Unemployment Fx_usd Avg_weather \n", "area \n", "USA 3.8 1.00 20.5 \n", "EUROZONE 6.5 1.09 18.0 \n", "JAPAN 2.6 143.50 15.0 \n", "UK 4.2 0.79 12.5 \n", "CANADA 5.1 1.36 10.0 \n", "AUSTRALIA 4.0 1.51 22.0 " ] }, "execution_count": 55, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Capitalize the first letter of each area name\n", "df1.index = df.index.str.upper() # Convert all area names to uppercase\n", "df1.columns = df.columns.str.capitalize() # Capitalize the first letter of each column name\n", "df1" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Data Visualization with Pandas\n", "\n", "DataFrames have all kinds of [useful plotting](https://pandas.pydata.org/pandas-docs/stable/visualization.html) built in. Note that by default `matplotlib` is used as the backend for plotting in Pandas. However, Pandas imports matplotlib for you in the background and you don't have to do it yourself. \n", "\n", "You can create various types of plots directly from DataFrames and Series using the `plot()` method. Here are some examples:" ] }, { "cell_type": "code", "execution_count": 56, "metadata": { "execution": { "iopub.execute_input": "2026-01-19T18:20:42.745258Z", "iopub.status.busy": "2026-01-19T18:20:42.745006Z", "iopub.status.idle": "2026-01-19T18:20:43.524047Z", "shell.execute_reply": "2026-01-19T18:20:43.523555Z" } }, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 56, "metadata": {}, "output_type": "execute_result" }, { "data": { "image/png": "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8fnY2C6f8znnc84+jMOb8znvj4LBoNra2iRJlZWVKi4uVlFRkWbMmKGff/5ZL730kmbNmqV77rlHZ8+e1aFDh/T5559rzpw5Ue3X1NToscce09mzZ50/1jF+hoaG9Ntvv0UdS0xMlNfr1cKFC/XGG2/o7rvv1h9//KEtW7aM2d7kyZNVV1enhoYGpaenKzs7W9u3b9fFixedladnn31Wp0+fVigUikpYkp6erry8PJWXl+vpp5/WBx98oJSUFDU2NiorK0vl5eVXPa6tW7fqueee05QpU/TII49oaGjISdEfK7skrq+pU6cqIyNDLS0tyszM1MDAgBobG2Oe+9577ykvL0/5+flqbm5WOBzWqlWrJF0J1FtbW9XV1SWfz6e2tjb19fURIN+Crmau+m8ul0uffvqpqqqq9OCDDyoUCunee+8dh57j33j//fdVVFSk+++/X9u2bdPcuXMViUR05MgR7dy5U+3t7YpEInrnnXf0+OOP65tvvtGuXbvivk5ubq7a2tqcV7s0NDTI4/E45YFAQH6/X0899ZSampp04cIFbd68eVQbAwMD+vjjj3Xfffeps7PzqlY28O8cPnxY4XBYtbW1o9KIV1ZWKhgMKhQKKSkpSZs2bVJ9fb16e3ujEhANDg6qoaFBlZWV8vl8OnPmjPr6+lRRUSHpSna+P//8U6FQSPPmzVNSUpKSkpJi9uda73888+W/cs27rDCmb7/91kpLS2369Ok2ZcoUKywstPb2dqe8paXFlixZYtOmTTOXy2XZ2dm2cuVKO3XqlJmZ7dixw9LS0mx4eHhU23///belp6dbU1PTDRsPYqupqTFJo778fr+ZmfX399vChQvN4/FYQUGBffnllzGTTYTD4ah2BwcHrb6+3rxer7ndbisuLrbe3l6nPCcnJ+Z1/2n3/PnztmLFCktNTTWPx2OlpaX2448/OvWvZtOomdmePXusoKDAXC6XTZ061R544IG4Nyvj2qxYscJJBHHkyBHLz883t9ttc+fOte7u7qgN2v8km9i7d68tWLDAXC6X5efnWygUctq7dOmSrVy50lJTUy0tLc3q6uqssbFxzE27GzZssJKSkus8WtxoY81VsX5XDA8PW0VFhXm9Xvvhhx9ucI9xLX799Vdbt26d5eTkmMvlsqysLHviiSecueOtt96yzMxMZ95obW2NmqOuZu44ceKEFRYWmtvttry8PNu3b5/l5ORYc3Ozc87Jkydt8eLF5nK5bNasWfbFF1+MSjbR0NBgGRkZlpycbNXV1dbc3BwzWQGuXVlZmT366KMxy44fP26S7Pjx43bw4EHLzc2122+/3crKyqylpcW590NDQ/bkk0/aXXfdZS6Xy+644w5bv369DQ4OOm2tWbPGMjIyTJK9+uqrZmajfjb+Mdb9HyvZxFjz5bVIMIsjlyEAYNwsXbpUubm5evfdd8c899SpU/L5fPruu+9UUFBw/TsHAMAthj1SAHCTC4fD6uzsVHd3twKBwHh3BwAAiD1SAHDTW7Vqlfr6+vT888/HtbcNAABcPzzaBwAAAABx4tE+AAAAAIgTgRQAAAAAxIlACgAAAADiRCAFAAAAAHEikAIAAACAOBFIAQAAAECcCKQAABNST0+PbrvtNi1dunS8uwIAmIB4jxQAYEJavXq1kpOTtXv3bvX39ys7OzvmeWamy5cvKzGRd9QDAK4eK1IAgAnnr7/+UkdHh+rq6lRWVqaPPvrIKevu7lZCQoK6urpUWFgot9uto0ePysy0fft2zZw5Ux6PR/PmzdP+/fudepcvX1Ztba18Pp88Ho/8fr/efvvtcRgdAOBmwL/fAAATzieffCK/3y+/36/ly5ervr5eL7/8shISEpxzXnzxRe3YsUMzZ85UWlqatmzZogMHDmjnzp3Ky8vT119/reXLl2vatGkqKSnRyMiI7rzzTnV0dMjr9aqnp0fPPPOMMjMzVVVVNY6jBQCMBx7tAwBMOMXFxaqqqtKGDRsUiUSUmZmp9vZ2BQIBdXd3a8mSJfrss89UXl4u6coKltfr1VdffaVFixY57axevVoXL17U3r17Y15n3bp1+v3336NWrgAAtwZWpAAAE8rJkyfV29urAwcOSJISExNVXV2tDz/8UIFAwDmvsLDQ+dzf369Lly7poYceimpreHhY8+fPd77ftWuXdu/erV9++UWDg4MaHh5WQUHB9R0QAOCmRCAFAJhQgsGgIpGIsrKynGNmpkmTJikcDjvHJk+e7HweGRmRJHV2dkbVkyS32y1J6ujo0MaNG9XU1KRFixYpJSVFb775po4dO3Y9hwMAuEkRSAEAJoxIJKLW1lY1NTXp4YcfjiqrqKjQnj17NGfOnFH1Zs+eLbfbrYGBAZWUlMRs++jRoyoqKtLatWudYz/99NP/dgAAgP8bBFIAgAnj8OHDCofDqq2tVWpqalRZZWWlgsGgmpubR9VLSUnRCy+8oI0bN2pkZESLFy/WhQsX1NPTo+TkZNXU1Cg3N1etra3q6uqSz+dTW1ub+vr65PP5btTwAAA3EdKfAwAmjGAwqEAgMCqIkq6sSH3//fc6ceJEzLqvvfaaXnnlFb3++uvKz89XaWmpDh065ARKa9as0bJly1RdXa0FCxbo3LlzUatTAIBbC1n7AAAAACBOrEgBAAAAQJwIpAAAAAAgTgRSAAAAABAnAikAAAAAiBOBFAAAAADEiUAKAAAAAOJEIAUAAAAAcSKQAgAAAIA4EUgBAAAAQJwIpAAAAAAgTgRSAAAAABCn/wDhqY+aabRFYwAAAABJRU5ErkJggg==", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "df.gdp_growth.plot(\n", " kind='line', \n", " title='GDP Growth by Area',\n", " ylabel=r'$ \\Delta y$ (%)',\n", " xlabel='Area', \n", " grid=True, \n", " figsize=(10, 5), \n", " legend=True,\n", " color='green',\n", " marker='o',\n", " linestyle='--'\n", ")" ] }, { "cell_type": "code", "execution_count": 57, "metadata": { "execution": { "iopub.execute_input": "2026-01-19T18:20:43.526330Z", "iopub.status.busy": "2026-01-19T18:20:43.526056Z", "iopub.status.idle": "2026-01-19T18:20:43.667812Z", "shell.execute_reply": "2026-01-19T18:20:43.667150Z" } }, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 57, "metadata": {}, "output_type": "execute_result" }, { "data": { "image/png": "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JSUlSZICAwM1efJknThxQkePHtWMGTNUuXLlPAkKAAAAAGa5r+K0b98+lSlTRnXq1NHq1as1Z84cHThwQA0aNFDjxo3166+/avHixXmVFQAAAABMcV+X6hUqVEgjR45U586d1bdvX3l4eOjjjz9W2bJl8yofAAAAAJguR5NDBAYGav369Wrfvr2aNGmiadOm5XYuAAAAALAb91Wcrl69qhEjRqht27Z6/fXX1bFjR+3du1f79u1T/fr1dfTo0bzKCQAAAACmua/iFBERoT179qh169Y6ceKE+vbtq5IlS2revHl655131LlzZ40YMSKvsgIAAACAKe7rHqdNmzbp4MGDCgoK0ksvvaSgoCDbuhYtWujAgQN66623cj0kAAAAAJjpvs44VapUSbNmzdJPP/2kmTNnyt/fP8P6IkWK6N13383VgAAAAABgtvsqTnPmzNHmzZtVu3ZtLV68WDNmzMirXAAAAABgN+7rUr1HH31UMTExeZUFAAAAAOxSjqYjzw6r1Wq4zYQJE/TYY4+paNGi8vHxUfv27XXixAnD/bZt26a6devKzc1NgYGBmjlzZm5EBgAAAIAsZbs4ValSRYsXL1ZKSso9t/v555/Vt29f/fvf/zY85rZt29S/f3/t2bNHGzduVGpqqsLCwpSYmHjXfU6fPq3w8HA1btxYBw8e1GuvvaZBgwZp+fLl2X0rAAAAAHBfsn2p3rRp0zRixAj1799fYWFhCgkJUdmyZeXm5qY//vhDx48f186dO3X8+HENGDBA/fr1MzzmunXrMizPnTtXPj4++v7779WkSZMs95k5c6YqVKigqVOnSvqr0MXExGjSpEnq1KlTdt8OAAAAAGRbtovTE088of3792vXrl1asmSJFi9erDNnzujmzZsqVaqUateure7du6tbt24qVqxYjsJcvXpVklSiRIm7brN7926FhYVlGGvZsqWioqJ0+/Ztubi4ZFiXnJys5ORk2/K1a9dylA0AAACA47qvySEkqUGDBmrQoEGuB7FarYqMjFSjRo1UvXr1u26XkJCg0qVLZxgrXbq0UlNTdenSJfn6+mZYN2HCBI0bNy7X8wIAAABwHHk2OcT9GjBggI4cOaLPPvvMcFuLxZJh+c5EFH8fl6RRo0bp6tWrtte5c+dyJzAAAAAAh3HfZ5zywsCBA7Vq1Spt375d5cuXv+e2ZcqU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", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "df.inflation.plot(\n", " kind='bar', \n", " title='Inflation Rate by Area', \n", " ylabel='Inflation Rate (%)', \n", " xlabel='Area', \n", " color=\"orange\",\n", " grid=False,\n", " figsize=(10, 5),\n", " legend=False,\n", " edgecolor='black',\n", " linewidth=1.5\n", ")" ] }, { "cell_type": "code", "execution_count": 58, "metadata": { "execution": { "iopub.execute_input": "2026-01-19T18:20:43.670411Z", "iopub.status.busy": "2026-01-19T18:20:43.670138Z", "iopub.status.idle": "2026-01-19T18:20:43.819364Z", "shell.execute_reply": "2026-01-19T18:20:43.818831Z" } }, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 58, "metadata": {}, "output_type": "execute_result" }, { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAA2QAAAHUCAYAAABVveuUAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjAsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvlHJYcgAAAAlwSFlzAAAPYQAAD2EBqD+naQAAZh9JREFUeJzt3XlclPX6//H3iDAsyaggmwuaJkcDzbRcqFxCcEGPecqOFmoababh0qJlaqV+M7VFW8zMTNwqtVI7CFpqJi5xpCTNNkstcEVwCxDv3x/8mOMIKBh4T/B6Ph48jtz3Nfdcc1946O3nnnsshmEYAgAAAABcddXMbgAAAAAAqioCGQAAAACYhEAGAAAAACYhkAEAAACASQhkAAAAAGASAhkAAAAAmIRABgAAAAAmIZABAAAAgEkIZAAAAABgEgIZAFSgb7/9VkOHDlXjxo3l4eEhDw8PXXfddXrwwQf19ddfO9ROnDhRFovF/uXp6al69eopKipKs2bN0smTJ4scf/DgwQ6PsVqtCgkJ0YQJE/Tnn3+Wqsd9+/ZpxIgRatasmby8vOTu7q6GDRvq3nvv1RdffCHDMMrlXPwVf/zxhyZOnKjU1NQi+wYPHqxrrrnm6jdVBjk5OXr99dfVsWNH+fj4yNXVVT4+PurUqZPmzJlTZLYXztTFxUW1atVSy5Yt9eCDD2rr1q1Fjv/rr786PKZatWry8fFRjx49lJycfLVe5l92/vx5LVy4UBEREfL19ZWrq6v8/PwUHR2tVatW6fz58xX23Bs2bJDFYtGGDRvs2z777DNNnDixwp4TACQCGQBUmDlz5qh169batm2bHnvsMa1evVpr1qxRXFycvvvuO9100036+eefizwuISFBycnJSkhI0PTp09WgQQM98cQTuv766/XNN98Uqffw8FBycrKSk5P18ccfq23btnruuec0aNCgy/b46aefKiwsTJ9++qkGDRqklStXau3atRo/fryOHTumLl266PPPPy+X8/FX/PHHH5o0aVKxgczZHTlyRB06dNCoUaMUEhKit99+W59//rnmzZunFi1a6IknntAjjzxS5HF33nmnkpOTtXnzZi1dulQDBw7U1q1b1b59ez322GPFPtfw4cOVnJysL7/8UlOnTtU333yjzp07a+fOnRX9Mv+yP//8Uz169NCgQYPk5+enN998U59//rneeustBQUF6a677tKqVasq7PlvvPFGJScn68Ybb7Rv++yzzzRp0qQKe04AkCQZAIByt3nzZqNatWpGr169jJycnGJrPvjgA+P333+3fz9hwgRDknHkyJEitampqYbNZjMaNGhg/Pnnn/btgwYNMry8vIrU33rrrYYk4+DBgyX2+NNPPxmenp7GTTfdZGRlZRVb88UXXxipqaklHsMwDOP06dOX3F8eduzYYUgy5s+fX2RfSefAWURGRhqurq7Gxo0bi91/9OhRY+HChQ7bJBnDhg0rUnvu3DljyJAhhiTjjTfesG/ft2+fIcl46aWXHOrXr19vSDLuv//+cnglf8358+eNM2fOlLj/4YcfNiQZCxYsKHb/Dz/8YHzzzTcV1V6xhg0bZvCfSgAqGitkAFABpkyZIhcXF82ZM0dubm7F1tx1110KCgoq1fFatmypp59+Wvv379eyZcsuW9+uXTtJ0m+//VZizcyZM3XmzBm98cYb8vb2LramU6dOatmypf37wssq//vf/+rOO+9UrVq11LhxY0kFKxxjx45Vo0aN5Obmprp162rYsGE6ceKE/fGPP/64bDab8vPz7duGDx8ui8Wil156yb7t2LFjqlatmmbNmqUNGzbopptukiTdd9999svyLr6U7KefflKPHj10zTXXqH79+ho9erRycnIueZ769Omj4ODgYi+Fa9u2rcNqyYcffqi2bdvKZrPJ09NT1157rYYMGXLJ4+/YsUOJiYl64IEHdNtttxVb4+Pjo3vvvfeSxynk4uKi2bNny9fX1+F8laQ0PweS1LBhQ0VHR2vlypVq0aKF3N3dde211+q1114rUpudna0xY8Y4zDkuLk6nT592qLNYLHr00Uf11ltvqVmzZrJarVqwYEGxz5+RkaF33nlHUVFRGjhwYLE11113nVq0aCGp4Gdt9OjRuuGGG2Sz2VS7dm21b99en3zySZHHFfYxZ84cNW3aVFarVc2bN9fSpUsd6i6+ZHHw4MF6/fXX7cco/Pr1118lSa+//rpuu+02+fn5ycvLS2FhYZo2bZry8vJKPtEAUAwCGQCUs/z8fH3xxRdq06aNAgMDy+24vXv3liRt2rTpsrU//fSTJKlOnTol1iQlJSkwMFBt2rQpcy99+/ZVkyZN9OGHH+qtt96SYRjq06ePpk+frpiYGK1Zs0ajRo3SggUL1KVLF3swioiIUHZ2trZv324/1rp16+Th4aGkpCT7tvXr18swDEVEROjGG2/U/PnzJUnPPPOM/fLM+++/316fl5en3r176/bbb9cnn3yiIUOG6OWXX9aLL754ydcxZMgQ7d+/v8hlmd9//722b9+u++67T5KUnJysu+++W9dee62WLl2qNWvW6Nlnn9W5c+cuefzC11Q4u/Lg4eGhiIgI7du3TwcPHrxkbWl+DgqlpqYqLi5OI0eO1MqVK9WhQwc99thjmj59ur3mzJkz6tixoxYsWKARI0boP//5j5588km999576t27d5H3G3788cd688039eyzz2rt2rW69dZbi33uL774Qnl5eerTp89l+5QK3pN3/PhxjRkzRh9//LGWLFmiW265RX379tX7779fpP7TTz/Va6+9pueee04fffSRgoOD1b9/f3300UclPsf48eN15513SpL9Zy45Odn+d/rnn3/WgAEDtHDhQq1evVpDhw7VSy+9pAcffLBUrwEA7ExeoQOASicjI8OQZPz73/8usu/cuXNGXl6e/ev8+fP2fZe6ZNEwDOPs2bOGJKN79+72bYWX6xUe78iRI8arr75qWCwW46abbrpkn+7u7ka7du2KbM/Pz3foMT8/v0iPzz77rMNjEhISDEnGtGnTHLYvW7bMkGS8/fbbhmEUXN7o5uZmPPfcc4ZhGMbBgwcNScaTTz5peHh42C/HjI2NNYKCguzHudwli5KMDz74wGF7jx49jJCQkEueg7y8PMPf398YMGCAw/YnnnjCcHNzM44ePWoYhmFMnz7dkGScOHHikse72EMPPWRIMr7//nuH7efPn3c4x+fOnXPYrxIuWSz05JNPGpKMbdu2GYbxv0sWX3zxRSMvL8/4888/jZSUFOOmm24yJBlr1qy5ZJ/BwcGGxWIpcnlq165dDW9vb/tlqVOnTjWqVatm7Nixw6Huo48+MiQZn332mcNrsNlsxvHjxy/53IZhGP/3f/9nSDISEhIuW1ucwr9XQ4cONVq1auWwT5Lh4eFhZGRkONT/4x//MJo0aWLf9sUXXxiSjC+++MK+rbSXLBb+nXn//fcNFxeXUr1mACjEChkAXEWtW7eWq6ur/WvGjBmlfqxRwt0OT58+bT9enTp1FBcXp+7du2vlypVX1GPfvn0dehwxYkSRmn/9618O3xeuMA0ePNhh+1133SUvLy+t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AABAZVbmFbJJkyZp5syZ6tevn7KysjRq1Cj17dtX1apV08SJEyugRQAAAAConMocyBYtWqS5c+dqzJgxql69uvr376933nlHzz77rLZu3VoRPQIAAABApVTmQJaRkaGwsDBJ0jXXXKOsrCxJUnR0tNasWVO+3QEAAABAJVbmQFavXj37h0I3adJEiYmJkqQdO3bIarWWb3cAAAD427roVgPlXg9UBmUOZHfccYfWr18vSXrsscc0fvx4XXfddRo4cKCGDBlS7g0CAADg72ftWunRR6WjR0tXf/RoQf3atRXbF+BsynyXxf/7v/+z//nOO+9U/fr19dVXX6lJkybq3bt3uTYHAACAv5/cXGn5cik9XRo7Vpo6VfL1Lbn+6NGCuoyMgsd17iy5uV29fgEz/eXPIWvbtq1GjRpFGAMAAICkgjA1ZYoUEFAQssaOLXml7MIwFhBQ8DjCGKqSUgeylJQUde7cWdnZ2UX2ZWVlqXPnzvrmm2/K9OQTJ06UxWJx+AoICLDvHzx4cJH97dq1czhGTk6Ohg8fLl9fX3l5eal37946ePCgQ01mZqZiYmJks9lks9kUExOjEydOONTs379fvXr1kpeXl3x9fTVixIgin7EGAACA0vH1LVgZu1QouziMXW4lDaiMSh3IZsyYoS5dusjb27vIPpvNpoiICL300ktlbuD6669Xenq6/WvXrl0O+7t16+aw/7PPPnPYHxcXp5UrV2rp0qXavHmzTp06pejoaOXn59trBgwYoNTUVCUkJCghIUGpqamKiYmx78/Pz1fPnj11+vRpbd68WUuXLtXy5cs1evToMr8eAAAAFCgulB07VrDv2DHCGCCV4T1k27Zt01NPPVXi/t69e2vevHllb6B6dYdVsYtZrdYS92dlZWnevHlauHChIiIiJEnx8fGqX7++1q1bp6ioKO3Zs0cJCQnaunWr2rZtK0maO3eu2rdvr7179yokJESJiYnavXu3Dhw4oKCgIEkFAXTw4MGaPHlysSEUAAAAl1cYygrD16RJUrduBf9LGAPKEMh+//131ahRo8T911xzjf12+GXx448/KigoSFarVW3bttWUKVN07bXX2vdv2LBBfn5+qlmzpjp27KjJkyfLz89PUsFllHl5eYqMjLTXBwUFKTQ0VFu2bFFUVJSSk5Nls9nsYUyS2rVrJ5vNpi1btigkJETJ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P3LkiMP+8+fPO1y+dyW8vLwUFhamH3/8UX369JFUsHoVGBhorzl8+LB9NSsgIEC5ubnKzMx0WCU7fPiwOnToYK85dOhQkec6cuSIw3G2bdvmsD8zM1N5eXlFVs4uZLVaZbVai2x3dXXlh7mccU6dDzNxPszEuTAP58NMnAvzcD7MpHyV9lyW+i6L9erVU1paWon7v/32W9WrV6+0hytWTk6O9uzZo8DAQDVq1EgBAQEOS6e5ubnauHGjPWy1bt1arq6uDjXp6elKS0uz17Rv315ZWVnavn27vWbbtm3KyspyqElLS1N6erq9JjExUVarVa1bt/5LrwkAAAAASlLqQNajRw89++yz+vPPP4vsO3v2rCZNmqSePXuW6cnHjBmjjRs3at++fdq2bZvuvPNOZWdna9CgQbJYLIqLi9OUKVO0cuVKpaWlafDgwfL09NSAAQMkSTabTUOHDtXo0aO1fv167dy5U/fee6/CwsLsd11s1qyZunXrptjYWG3dulVbt25VbGysoqOjFRISIkmKjIxU8+bNFRMTo507d2r9+vUaM2aMYmNjufQQAAAAQIUp9SWL48aN0wcffKCQkBA9+uijatq0qSwWi77//nvNnj1b586d07hx48r05AcPHlT//v119OhR1alTR+3atdPWrVsVHBwsSXriiSd09uxZPfLII8rMzFTbtm2VmJioGjVq2I/x8ssvq3r16urXr5/Onj2r22+/Xe+9955cXFzsNYsWLdKIESPsd2Ps3bu3Zs+ebd/v4uKiNWvW6JFHHlF4eLg8PDw0YMAATZ8+vUyvBwAAAADKotSBzN/fX1u2bNHDDz+sp556SoZhSCq4GUbXrl31xhtvXPL9VsVZunTpJfdbLBZNnDhREydOLLHG3d1ds2bN0qxZs0qsqV27tuLj4y/5XA0aNNDq1asvWQMAAAAA5anUgUySGjVqpISEBB0/flw//fSTJKlJkyaqXbt2hTQHAAAAAJVZmQJZodq1a+vmm28u714AAAAAoEop9U09AAAAAADli0AGAAAAACYhkAEAAACASQhkAAAAAGASAhkAAAAAmIRABgAAAAAmIZABAAAAgEkIZAAAAABgEgIZAAAAAJiEQAYAAAAAJiGQAQAAAIBJCGQAAAAAYBICGQAAAACYhEAGAAAAACYhkAEAAACASQhkAAAAAGASAhkAAAAAmIRABgAAAAAmIZABAAAAgEkIZAAAAABgEgIZAAAAAJiEQAYAAAAAJiGQAQAAAIBJCGQAAAAAYBICGQAAAACYhEAGAAAAACYhkAEAAACASQhkAAAAAGASAhkAAAAAmIRABgAAAAAmIZABAAAAgEkIZAAAAABgEgIZAAAAAJiEQAYAAAAAJiGQAQAAAIBJCGQAAAAAYBICGQAAAACYhEAGAAAAACYhkAEAAACASQhkAAAAAGASAhkAAAAAmIRABgAAAAAmIZABAAAAgEkIZAAAAABgEgIZAAAAAJjEaQLZ1KlTZbFYFBcXZ982ePBgWSwWh6927do5PC4nJ0fDhw+Xr6+vvLy81Lt3bx08eNChJjMzUzExMbLZbLLZbIqJidGJEyccavbv369evXrJy8tLvr6+GjFihHJzcyvq5QIAAACAcwSyHTt26O2331aLFi2K7OvWrZvS09PtX5999pnD/ri4OK1cuVJLly7V5s2bderUKUVHRys/P99eM2DAAKWmpiohIUEJCQlKTU1VTEyMfX9+fr569uyp06dPa/PmzVq6dKmWL1+u0aNHV9yLBgAAAFDlVTe7gVOnTumee+7R3Llz9cILLxTZb7VaFRAQUOxjs7KyNG/ePC1cuFARERGSpPj4eNWvX1/r1q1TVFSU9uzZo4SEBG3dulVt27aVJM2dO1ft27fX3r17FRISosTERO3evVsHDhxQUFCQJGnGjBkaPHiwJk+eLG9v7wp69QAAAACqMtMD2bBhw9SzZ09FREQUG8g2bNggPz8/1axZUx07dtTkyZPl5+cnSUpJSVFeXp4iIyPt9UFBQQoNDdWWLVsUFRWl5ORk2Ww2exiTpHbt2slms2nLli0KCQlRcnKyQkND7WFMkqKiopSTk6OUlBR17ty52N5zcnKUk5Nj/z47O1uSlJeXp7y8vL92YiBJ9vPI+XQezMT5MBPnwjycDzNxLszD+TCTilHa82lqIFu6dKn++9//aseOHcXu7969u+666y4FBwdr3759Gj9+vLp06aKUlBRZrVZlZGTIzc1NtWrVcnicv7+/MjIyJEkZGRn2AHchPz8/hxp/f3+H/bVq1ZKbm5u9pjhTp07VpEmTimxPTEyUp6fnpV88yiQpKcnsFnARZuJ8mIlzYR7Oh5k4F+bhfJhJ+Tpz5kyp6kwLZAcOHNBjjz2mxMREubu7F1tz99132/8cGhqqNm3aKDg4WGvWrFHfvn1LPLZhGLJYLPbvL/zzX6m52NixYzVq1Cj799nZ2apfv74iIyO5zLGc5OXlKSkpSV27dpWrq6vZ7UDMxBkxE+fCPJwPM3EuzMP5MJOKUXj13OWYFshSUlJ0+PBhtW7d2r4tPz9fmzZt0uzZs5WTkyMXFxeHxwQGBio4OFg//vijJCkgIEC5ubnKzMx0WCU7fPiwOnToYK85dOhQkec/cuSIfVUsICBA27Ztc9ifmZmpvLy8IitnF7JarbJarUW2u7q68sNczjinzoeZOB9m4lyYh/NhJs6FeTgfZlK+SnsuTbvL4u23365du3YpNTXV/tWmTRvdc889Sk1NLRLGJOnYsWM6cOCAAgMDJUmtW7eWq6urw/Jqenq60tLS7IGsffv2ysrK0vbt2+0127ZtU1ZWlkNNWlqa0tPT7TWJiYmyWq0OgREAAAAAypNpK2Q1atRQaGiowzYvLy/5+PgoNDRUp06d0sSJE/Wvf/1LgYGB+vXXXzVu3Dj5+vrqjjvukCTZbDYNHTpUo0ePlo+Pj2rXrq0xY8YoLCzMftfFZs2aqVu3boqNjdWcOXMkSQ888ICio6MVEhIiSYqMjFTz5s0VExOjl156ScePH9eYMWMUGxvLpYcAAAAAKoxTfA5ZcVxcXLRr1y7985//VNOmTTVo0CA1bdpUycnJqlGjhr3u5ZdfVp8+fdSvXz+Fh4fL09NTq1atclhhW7RokcLCwhQZGanIyEi1aNFCCxcudHiuNWvWyN3dXeHh4erXr5/69Omj6dOnX9XXDAAAAKBqMf229xfasGGD/c8eHh5au3btZR/j7u6uWbNmadasWSXW1K5dW/Hx8Zc8ToMGDbR69epS9woAAAAAf5XTrpABAAAAQGVHIAMAAAAAkxDIAAAAAMAkBDIAAAAAMAmBDAAAAABMQiADAAAAAJMQyAAAAADAJAQyAAAAADAJgQwAAAAATEIgAwAAAACTEMgAAAAAwCQEMgAAAAAwCYEMAAAAAExCIAMAAAAAkxDIAAAAAMAkBDIAAAAAMAmBDAAAAABMQiADAAAAAJMQyAAAAADAJAQyAAAAADAJgQwAAAAATEIgAwAAAACTEMgAAAAAwCQEMgAAAAAwCYEMAAAAAExCIAMAAAAAkxDIAAAAAMAkBDIAAAAAMAmBDAAAAABMQiADAAAAAJMQyAAAAADAJAQyAAAAADAJgQwAAAAATEIgAwAAAACTEMgAAAAAwCQEMgAAAAAwCYEMAAAAAExCIAMAAAAAkxDIAAAAAMAkBDIAAAAAMAmBDAAAAABMQiADAAAAAJMQyAAAAADAJASySiA3t2LrAQAAAFQMAtnf3Nq10qOPSkePlq7+6NGC+rVrK7YvAAAAAJdHIPsby82Vli+X0tOlsWMvH8qOHi2oS08veBwrZQAAAIC5CGR/Y25u0pQpUkCAlJFx6VBWGMYyMgrqp0wpeDwAAAAA8zhNIJs6daosFovi4uLs2wzD0MSJExUUFCQPDw916tRJ3333ncPjcnJyNHz4cPn6+srLy0u9e/fWwYMHHWoyMzMVExMjm80mm82mmJgYnThxwqFm//796tWrl7y8vOTr66sRI0Yo92+whOTrK02deulQdnEYmzq14HEAAAAAzOUUgWzHjh16++231aJFC4ft06ZN08yZMzV79mzt2LFDAQEB6tq1q06ePGmviYuL08qVK7V06VJt3rxZp06dUnR0tPLz8+01AwYMUGpqqhISEpSQkKDU1FTFxMTY9+fn56tnz546ffq0Nm/erKVLl2r58uUaPXp0xb/4cnCpUEYYAwAAAJyX6YHs1KlTuueeezR37lzVqlXLvt0wDL3yyit6+umn1bdvX4WGhmrBggU6c+aMFi9eLEnKysrSvHnzNGPGDEVERKhVq1aKj4/Xrl27tG7dOknSnj17lJCQoHfeeUft27dX+/btNXfuXK1evVp79+6VJCUmJmr37t2Kj49Xq1atFBERoRkzZmju3LnKzs6++iflChQXyvbsIYwBAAAAzqy62Q0MGzZMPXv2VEREhF544QX79n379ikjI0ORkZH2bVarVR07dtSWLVv04IMPKiUlRXl5eQ41QUFBCg0N1ZYtWxQVFaXk5GTZbDa1bdvWXtOuXTvZbDZt2bJFISEhSk5OVmhoqIKCguw1UVFRysnJUUpKijp37lxs7zk5OcrJybF/Xxje8vLylJeX99dPThnZbNLzz0uTJkmHDklPP12wvV49acKEgv0mtPWXFJ5HM84nisdMnA8zcS7Mw/kwE+fCPJwPM6kYpT2fpgaypUuX6r///a927NhRZF9GRoYkyd/f32G7v7+/fvvtN3uNm5ubw8paYU3h4zMyMuTn51fk+H5+fg41Fz9PrVq15ObmZq8pztSpUzVp0qQi2xMTE+Xp6Vni4ypat25Ft23bdvX7KE9JSUlmt4CLMBPnw0ycC/NwPszEuTAP58NMyteZM2dKVWdaIDtw4IAee+wxJSYmyt3dvcQ6i8Xi8L1hGEW2XezimuLqr6TmYmPHjtWoUaPs32dnZ6t+/fqKjIyUt7f3JXusKMeO/W+FrJC/f8EKmY+PKS39JXl5eUpKSlLXrl3l6upqdjsQM3FGzMS5MA/nw0ycC/NwPsykYpT2rU+mBbKUlBQdPnxYrVu3tm/Lz8/Xpk2bNHv2bPv7uzIyMhQYGGivOXz4sH01KyAgQLm5ucrMzHRYJTt8+LA6dOhgrzl0YTr5/44cOeJwnG0XLSFlZmYqLy+vyMrZhaxWq6xWa5Htrq6upvwwHz0qjR//v/eMjRolzZwpHTxYsP3v/B4ys84pSsZMnA8zcS7Mw/kwE+fCPJwPMylfpT2Xpt3U4/bbb9euXbuUmppq/2rTpo3uuecepaam6tprr1VAQIDD0mlubq42btxoD1utW7eWq6urQ016errS0tLsNe3bt1dWVpa2b99ur9m2bZuysrIcatLS0pSenm6vSUxMlNVqdQiMzqy4uyk2a3b5W+IDAAAAMI9pK2Q1atRQaGiowzYvLy/5+PjYt8fFxWnKlCm67rrrdN1112nKlCny9PTUgAEDJEk2m01Dhw7V6NGj5ePjo9q1a2vMmDEKCwtTRESEJKlZs2bq1q2bYmNjNWfOHEnSAw88oOjoaIWEhEiSIiMj1bx5c8XExOill17S8ePHNWbMGMXGxpp26WFZXOrW9oV3XyzcP3bs33ulDAAAAKhMTL/t/aU88cQTiouL0yOPPKI2bdro999/V2JiomrUqGGvefnll9WnTx/169dP4eHh8vT01KpVq+Ti4mKvWbRokcLCwhQZGanIyEi1aNFCCxcutO93cXHRmjVr5O7urvDwcPXr1099+vTR9OnTr+rrvRKl+Zyx0nx4NAAAAICrz/Tb3l9ow4YNDt9bLBZNnDhREydOLPEx7u7umjVrlmbNmlViTe3atRUfH3/J527QoIFWr15dlnZNl5srjRtXus8Zu3ilbNw4afZsyc3t6vYMAAAA4H+ceoUMl+bmJv3rX1JgYOkuQywMZYGBBY8jjAEAAADmcqoVMpRdVJTUuXPpw5WvLytjAAAAgLNghawSKGu4IowBAAAAzoFABgAAAAAmIZABAAAAgEkIZAAAAABgEgIZAAAAAJiEQAYAAAAAJiGQAQAAAIBJCGQAAAAAYBI+GLocGYYhScrOzja5k8ojLy9PZ86cUXZ2tlxdXc1uB2ImzoiZOBfm4XyYiXNhHs6HmVSMwkxQmBFKQiArRydPnpQk1a9f3+ROAAAAADiDkydPymazlbjfYlwusqHUzp8/rz/++EM1atSQxWIxu51KITs7W/Xr19eBAwfk7e1tdjsQM3FGzMS5MA/nw0ycC/NwPsykYhiGoZMnTyooKEjVqpX8TjFWyMpRtWrVVK9ePbPbqJS8vb35Pwgnw0ycDzNxLszD+TAT58I8nA8zKX+XWhkrxE09AAAAAMAkBDIAAAAAMAmBDE7NarVqwoQJslqtZreC/4+ZOB9m4lyYh/NhJs6FeTgfZmIubuoBAAAAACZhhQwAAAAATEIgAwAAAACTEMgAAAAAwCQEMgAAAAAwCYEMpnvjjTfUqFEjubu7q3Xr1vryyy8vWb9o0SK1bNlSnp6eCgwM1H333adjx45dpW4rt02bNqlXr14KCgqSxWLRxx9/fNnHbNy4Ua1bt5a7u7uuvfZavfXWWxXfaBVS1pmsWLFCXbt2VZ06deTt7a327dtr7dq1V6fZKuJK/p4U+uqrr1S9enXdcMMNFdZfVXMl88jJydHTTz+t4OBgWa1WNW7cWO+++27FN1tFXMlM+N1ecaZOnaqbbrpJNWrUkJ+fn/r06aO9e/de9nH8fr96CGQw1bJlyxQXF6enn35aO3fu1K233qru3btr//79xdZv3rxZAwcO1NChQ/Xdd9/pww8/1I4dO3T//fdf5c4rp9OnT6tly5aaPXt2qer37dunHj166NZbb9XOnTs1btw4jRgxQsuXL6/gTquOss5k06ZN6tq1qz777DOlpKSoc+fO6tWrl3bu3FnBnVYdZZ1JoaysLA0cOFC33357BXVWNV3JPPr166f169dr3rx52rt3r5YsWaJ//OMfFdhl1VLWmfC7vWJt3LhRw4YN09atW5WUlKRz584pMjJSp0+fLvEx/H6/ygzARDfffLPx0EMPOWz7xz/+YTz11FPF1r/00kvGtdde67DttddeM+rVq1dhPVZVkoyVK1desuaJJ54w/vGPfzhse/DBB4127dpVYGdVV2lmUpzmzZsbkyZNKv+GUKaZ3H333cYzzzxjTJgwwWjZsmWF9lVVlWYe//nPfwybzWYcO3bs6jRVxZVmJvxuv7oOHz5sSDI2btxYYg2/368uVshgmtzcXKWkpCgyMtJhe2RkpLZs2VLsYzp06KCDBw/qs88+k2EYOnTokD766CP17NnzarSMiyQnJxeZX1RUlL7++mvl5eWZ1BUudP78eZ08eVK1a9c2u5Uqbf78+fr55581YcIEs1up8j799FO1adNG06ZNU926ddW0aVONGTNGZ8+eNbu1Kovf7VdXVlaWJF3y9wK/368uAhlMc/ToUeXn58vf399hu7+/vzIyMop9TIcOHbRo0SLdfffdcnNzU0BAgGrWrKlZs2ZdjZZxkYyMjGLnd+7cOR09etSkrnChGTNm6PTp0+rXr5/ZrVRZP/74o5566iktWrRI1atXN7udKu+XX37R5s2blZaWppUrV+qVV17RRx99pGHDhpndWpXF7/arxzAMjRo1SrfccotCQ0NLrOP3+9VFIIPpLBaLw/eGYRTZVmj37t0aMWKEnn32WaWkpCghIUH79u3TQw89dDVaRTGKm19x23H1LVmyRBMnTtSyZcvk5+dndjtVUn5+vgYMGKBJkyapadOmZrcDFawaWywWLVq0SDfffLN69OihmTNn6r333mOVzCT8br96Hn30UX377bdasmTJZWv5/X718E91MI2vr69cXFyKrIYdPny4yL/KFJo6darCw8P1+OOPS5JatGghLy8v3XrrrXrhhRcUGBhY4X3jfwICAoqdX/Xq1eXj42NSV5AKbpgzdOhQffjhh4qIiDC7nSrr5MmT+vrrr7Vz5049+uijkgoCgWEYql69uhITE9WlSxeTu6xaAgMDVbduXdlsNvu2Zs2ayTAMHTx4UNddd52J3VVN/G6/OoYPH65PP/1UmzZtUr169S5Zy+/3q4sVMpjGzc1NrVu3VlJSksP2pKQkdejQodjHnDlzRtWqOf7Yuri4SPrfv9zg6mnfvn2R+SUmJqpNmzZydXU1qSssWbJEgwcP1uLFi3kPhsm8vb21a9cupaam2r8eeughhYSEKDU1VW3btjW7xSonPDxcf/zxh06dOmXf9sMPP6hatWqX/Y9UVAx+t1cswzD06KOPasWKFfr888/VqFGjyz6G3+9XF4EMpho1apTeeecdvfvuu9qzZ49Gjhyp/fv32y9TGDt2rAYO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33TjUlq0aOHwfWBgoA4fPlxi/dmzZ+Xu7u6wzdXVVa+//rr27dunHTt26JZbbtGoUaM0YsQIpaam6uOPP9Y333yjdu3aacSIEQ6P9fDwcLjZCgDgr6tudgMAgKqnSZMmslgs+v777x22X3vttZIK/sO/NI4dO6YjR46oUaNGDtuXLVum5s2bq2bNmvLx8bnkMa677roifdSpU0d16tSRn59fkfqLL7EsLhAWKtzeqVMn+x0b09LSdOutt+rnn3/Wxo0bdeLECbVu3Vo1atS47Ot1dXUtcvzz58+XWO/r66tdu3Zd8piff/65du/erXnz5unxxx9Xjx495OXlpX79+mn27NkOtcePH1edOnUu2ycAoPRYIQMAXHU+Pj7q2rWrZs+erdOnT1/xcV599VVVq1ZNffr0cdhev359NW7c+LJhTJL69++vvXv3XvJ9aJfSvHlzpaamOryOr776StWqVVPTpk0l/e99ZC+88IJatmwpb29vdezYURs3brS/f6xQ4epbfn7+FfVzoVatWun777+330XxYn/++aeGDRumOXPmyMXFRfn5+fb32uXl5RXpIS0tTa1atfrLfQEA/odABgAwxRtvvKFz586pTZs2WrZsmfbs2aO9e/cqPj5e33//vVxcXBzqT548qYyMDB04cECbNm3SAw88oBdeeEGTJ09WkyZNrriPf//737rzzjv173//W88995y2bdumX3/9VRs3btSyZcuK9HGxe+65R+7u7ho0aJDS0tL0xRdfaPjw4YqJiZG/v78k2d9HFh8fr06dOkkquPwwNzdX69evt2+TpODgYFksFq1evVpHjhwpcslkWXTu3FmnT5/Wd999V+z+5557Tj179rSHrPDwcK1YsULffvutZs+eXeQyyi+//FKRkZFX3A8AoCgCGQDAFI0bN9bOnTsVERGhsWPHqmXLlmrTpo1mzZqlMWPG6Pnnn3eof/bZZxUYGKgmTZooJiZGWVlZWr9+/V/+sGKLxaJly5bplVde0Weffabbb79dISEhGjJkiOrXr6/Nmzdf8vGenp5au3atjh8/rptuukl33nmnbr/99iKX+3Xu3Fn5+fn28GWxWHTrrbdKkm655RZ7Xd26dTVp0iQ99dRT8vf3t9+t8Ur4+Piob9++WrRoUZF9aWlp+vDDDzVp0iT7tjvvvFM9e/bUrbfeqm+//dbhDo/JycnKysrSnXfeecX9AACKshglXccAAAD+9nbt2qWIiAj99NNPpXqfWknuuusutWrVSuPGjSvH7gAArJABAFCJhYWFadq0aX/pdvU5OTlq2bKlRo4cWX6NAQAksUIGAAAAAKZhhQwAAAAATEIgAwAAAACTEMgAAAAAwCQEMgAAAAAwCYEMAAAAAExCIAMAAAAAkxDIAAAAAMAkBDIAAAAAMAmBDAAAAABM8v8A5JqHuj20eWwAAAAASUVORK5CYII=", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "df.plot(\n", " kind=\"scatter\", \n", " x=\"gdp_growth\", \n", " y=\"gdp_per_capita\", \n", " title=\"GDP Growth vs GDP per Capita\",\n", " xlabel=\"GDP Growth (%)\",\n", " ylabel=\"GDP per Capita ($)\",\n", " grid=True,\n", " figsize=(10, 5),\n", " color=\"blue\",\n", " marker=\"x\",\n", " s=100, # Size of the markers\n", " alpha=0.7, # Transparency of the markers\n", " linewidth=1.5 # Edge width of the markers\n", ") " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Importing and Exporting Data\n", "\n", "We have seen how to create DataFrames from scratch. However, in practice, we often need to load data from external files or databases. Pandas provides a variety of functions to read and write data in different formats. Data can be imported from CSV, Excel, and more. To read a CSV file into a DataFrame, you can use the `pd.read_csv()` function.\n", "\n", "```python\n", "file_csv ='./data.csv'\n", "data = pd.read_csv(file_csv)\n", "```\n", "\n", "To read an Excel file, you can use the `pd.read_excel()` function.\n", "\n", "```python\n", "file_excel = './data.xlsx'\n", "data = pd.read_excel(file_excel, sheet_name='Sheet1')\n", "```\n", "\n", "To write a DataFrame to a CSV file, you can use the `to_csv()` method.\n", "\n", "```python\n", "df.to_csv('output.csv', index=False)\n", "```\n", "\n", "To write a DataFrame to an Excel file, you can use the `to_excel()` method.\n", "\n", "```python\n", "df.to_excel('output.xlsx', sheet_name='Sheet1', index=False)\n", "```\n", "\n", "We will cover these and other data I/O methods in more detail in later sections of the course.\n", "\n", "\n", "\n", "#### Grouping and Aggregating Data\n", "\n", "One of the most powerful features of Pandas is the ability to group data by one or more columns and then apply aggregate functions to each group. This is done using the `groupby()` method, which splits the data into groups based on some criteria, applies a function to each group, and then combines the results." ] }, { "cell_type": "code", "execution_count": 59, "metadata": { "execution": { "iopub.execute_input": "2026-01-19T18:20:43.821880Z", "iopub.status.busy": "2026-01-19T18:20:43.821609Z", "iopub.status.idle": "2026-01-19T18:20:43.829737Z", "shell.execute_reply": "2026-01-19T18:20:43.829080Z" } }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
areayeargdp_growthinflation
0USA20232.54.1
1USA20242.13.2
2Eurozone20230.95.4
3Eurozone20241.32.5
4Japan20231.23.3
5Japan20240.71.0
\n", "
" ], "text/plain": [ " area year gdp_growth inflation\n", "0 USA 2023 2.5 4.1\n", "1 USA 2024 2.1 3.2\n", "2 Eurozone 2023 0.9 5.4\n", "3 Eurozone 2024 1.3 2.5\n", "4 Japan 2023 1.2 3.3\n", "5 Japan 2024 0.7 1.0" ] }, "execution_count": 59, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Create a sample DataFrame with multiple years\n", "df_multi_year = pd.DataFrame({\n", " \"area\": [\"USA\", \"USA\", \"Eurozone\", \"Eurozone\", \"Japan\", \"Japan\"],\n", " \"year\": [2023, 2024, 2023, 2024, 2023, 2024],\n", " \"gdp_growth\": [2.5, 2.1, 0.9, 1.3, 1.2, 0.7],\n", " \"inflation\": [4.1, 3.2, 5.4, 2.5, 3.3, 1.0]\n", "})\n", "df_multi_year" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "To calculate the average GDP growth and inflation for each area across all years:" ] }, { "cell_type": "code", "execution_count": 60, "metadata": { "execution": { "iopub.execute_input": "2026-01-19T18:20:43.832144Z", "iopub.status.busy": "2026-01-19T18:20:43.831904Z", "iopub.status.idle": "2026-01-19T18:20:43.841351Z", "shell.execute_reply": "2026-01-19T18:20:43.840837Z" } }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
yeargdp_growthinflation
area
Eurozone2023.51.103.95
Japan2023.50.952.15
USA2023.52.303.65
\n", "
" ], "text/plain": [ " year gdp_growth inflation\n", "area \n", "Eurozone 2023.5 1.10 3.95\n", "Japan 2023.5 0.95 2.15\n", "USA 2023.5 2.30 3.65" ] }, "execution_count": 60, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_multi_year.groupby(\"area\").mean()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "You can also apply multiple aggregation functions at once using `agg()`:" ] }, { "cell_type": "code", "execution_count": 61, "metadata": { "execution": { "iopub.execute_input": "2026-01-19T18:20:43.843637Z", "iopub.status.busy": "2026-01-19T18:20:43.843416Z", "iopub.status.idle": "2026-01-19T18:20:43.856796Z", "shell.execute_reply": "2026-01-19T18:20:43.856293Z" } }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
gdp_growthinflation
meanstdminmax
area
Eurozone1.100.2828432.55.4
Japan0.950.3535531.03.3
USA2.300.2828433.24.1
\n", "
" ], "text/plain": [ " gdp_growth inflation \n", " mean std min max\n", "area \n", "Eurozone 1.10 0.282843 2.5 5.4\n", "Japan 0.95 0.353553 1.0 3.3\n", "USA 2.30 0.282843 3.2 4.1" ] }, "execution_count": 61, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_multi_year.groupby(\"area\").agg({\n", " \"gdp_growth\": [\"mean\", \"std\"],\n", " \"inflation\": [\"min\", \"max\"]\n", "})" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Grouping by multiple columns is also possible:" ] }, { "cell_type": "code", "execution_count": 62, "metadata": { "execution": { "iopub.execute_input": "2026-01-19T18:20:43.859152Z", "iopub.status.busy": "2026-01-19T18:20:43.858795Z", "iopub.status.idle": "2026-01-19T18:20:43.865803Z", "shell.execute_reply": "2026-01-19T18:20:43.865332Z" } }, "outputs": [ { "data": { "text/plain": [ "area high_growth\n", "Eurozone False 5.40\n", " True 2.50\n", "Japan False 1.00\n", " True 3.30\n", "USA True 3.65\n", "Name: inflation, dtype: float64" ] }, "execution_count": 62, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Group by both area and whether gdp_growth is above 1%\n", "df_multi_year[\"high_growth\"] = df_multi_year[\"gdp_growth\"] > 1.0\n", "df_multi_year.groupby([\"area\", \"high_growth\"])[\"inflation\"].mean()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The `groupby()` method is essential for data analysis tasks like computing summary statistics by category, creating pivot tables, and preparing data for visualization.\n", "\n", "\n", ":::{.callout-tip}\n", "### Scaling Beyond Pandas: PySpark\n", "\n", "While Pandas excels at handling data that fits in memory, real-world big data applications often involve datasets too large for a single machine. [PySpark](https://spark.apache.org/docs/latest/api/python/) is the Python API for Apache Spark, a distributed computing framework that can process massive datasets across clusters of computers. PySpark DataFrames offer a similar interface to Pandas but distribute computations across many machines. For the purposes of this course, we will focus on Pandas, but it's worth noting that many concepts learned here can be transferred to PySpark when working with big data.\n", ":::" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3", "path": "/usr/local/share/jupyter/kernels/python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.13.5" } }, "nbformat": 4, "nbformat_minor": 4 }