Left, Right & Outer Joins

Python · Combining DataFrames (SQL Joins & Unions)

Theory

The how argument picks the join type. how='left' keeps every row of the left table and fills columns from the right with NaN where there is no match - the usual choice for 'all customers, with their orders if any'. how='right' is the mirror image, and how='outer' keeps every key from both sides (SQL FULL OUTER JOIN). Row order: left joins keep the left table's order; outer joins sort the keys.

indicator=True adds a _merge column saying 'both', 'left_only' or 'right_only' for each row, which is the quickest way to audit a join. validate='one_to_one', 'one_to_many' or 'many_to_one' makes pandas raise a MergeError if the keys are not as unique as you expect, catching accidental row explosions before they corrupt totals. Note that an int column that gains NaN from a left join turns into float64.

Why we use it

Business questions often need unmatched rows: customers who never ordered, products with no sales, orders with a missing customer. Left and outer joins keep those rows, and indicator and validate show you exactly what matched.

When to use it

Use left when the left table is the 'master list' you must not lose, outer when reconciling two sources, and right rarely (swap the tables and use left instead). Add validate= whenever one side should have unique keys.

How it works

  1. left.merge(right, on='key', how=...)
  2. Match keys between the two tables
  3. Key only in the left table? Yes: Kept for left/outer, NaN right cols. No: Next check.
  4. Key only in the right table? Yes: Kept for right/outer, NaN left cols. No: Matched row.
  5. Optional: _merge column (indicator) and key checks (validate)
  6. Joined DataFrame

Syntax

left.merge(right, on='key', how='left' | 'right' | 'outer')
left.merge(right, on='key', how='outer', indicator=True)
left.merge(right, on='key', validate='one_to_many')

Example

all_cust = customers.merge(orders, on='cust_id', how='left')
audit = customers.merge(orders, on='cust_id', how='outer', indicator=True)

Key points

Python topics

Getting Started

Variables & Data Types

Operators

Strings

Lists

Tuples

Sets

Dictionaries

Control Flow

Loops

Functions & OOP

Working with Data

Tooling & Errors

File Handling

Exception Handling

NumPy Library

Pandas Basics

Data Cleaning

Combining DataFrames (SQL Joins & Unions)

GroupBy & SQL-Style Analytics

Reshaping & Workflow

Data Visualization

Machine Learning (Scikit-Learn)

Advanced Python & AI

T
Tech Town
Log InSign Up Free
Home SQL Python DSA Power BI Snowflake Databricks Spark Gen AI Practice Problems Contest Blog

Python for Data Analysts

From basics to business insights — the complete step-by-step Python roadmap. Click any topic in the sidebar to open it right here.

{{ sectionCount }}
Sections
{{ topicCount }}
Topics
Free
Forever
Hands-on practice Practice Python Online 141 Python questions for data analysts — strings, records, dates, statistics and regex — with hidden tests and instant verdicts. Start practising →
Section {{ sec.num }}

{{ sec.label }}

Python  /  {{ current.sectionLabel }}  /  {{ current.name }}

{{ current.name }}

Theory

{{ current.def }}

Why we use it

{{ rich.why }}

When to use it

{{ rich.when }}

Diagram

{{ rich.dg.caption }}

{{ tb.title }}
{{ c.v }}
{{ rich.dg.op }}
➜
{{ rich.dg.output.title }}
{{ c.v }}
{{ nd.label }}
{{ nd.sub }}
{{ nd.label }}
{{ nd.sub }}
{{ rich.dg.left.title }}
{{ it }}
{{ rich.dg.right.title }}
{{ it }}
Flowchart — how it works
{{ nd.text }}
{{ nd.text }}
◇ {{ nd.text }}
Yes → {{ nd.yes }}
No → {{ nd.no }}
Syntax
{{ current.syntax }}
Example
{{ current.example }}
▶ Try It Live — runs real Python 3.12 in your browser (first run loads the engine)
{{ liveOutput }}
{{ liveError }}
Key Points — click to check off as you learn
  • {{ pt.mark }} {{ pt.text }}

Share this topic