isin() and between() Filters
Select rows where a column value is in a list with isin() or within a numeric range with between().
isin() and between() Filters is a free Pandas & NumPy Academy lesson on CoddyKit — lesson 3 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the Pandas & NumPy Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.
The isin() Method Overview
isin() checks whether each element of a Series is contained in a given list (or set) of values. It returns a boolean Series that you can use directly for row filtering. This is more concise and often faster than chaining multiple == comparisons with |.
For example, instead of (df['country'] == 'USA') | (df['country'] == 'UK'), you write df['country'].isin(['USA', 'UK']).
import pandas as pd
df = pd.DataFrame({
'country': ['USA', 'Germany', 'UK', 'France', 'USA'],
'sales': [400, 200, 150, 300, 600]
})
# Check membership
mask = df['country'].isin(['USA', 'UK'])
print(mask.tolist()) # [True, False, True, False, True]
result = df[mask]
print(result)
# country sales
# 0 USA 400
# 2 UK 150
# 4 USA 600isin() with Sets for Speed
You can pass a Python set instead of a list to isin(). Membership look-up in a set is O(1) — it doesn't get slower as the list grows. This matters when your allowed values list has thousands of entries, making set-based isin() significantly faster than list-based isin().
import pandas as pd
df = pd.DataFrame({
'sku': ['A001', 'B002', 'A003', 'C004', 'B005'],
'qty': [10, 5, 3, 8, 12]
})
# Use a set for fast membership check
allowed_skus = {'A001', 'A003', 'B005'}
result = df[df['sku'].isin(allowed_skus)]
print(result)
# sku qty
# 0 A001 10
# 2 A003 3
# 4 B005 12Negating isin() with ~
Combine isin() with the ~ operator to filter rows where a column does not contain the specified values. This is the cleanest way to exclude a list of specific values, far more readable than building a chain of != comparisons.
import pandas as pd
df = pd.DataFrame({
'status': ['active', 'cancelled', 'shipped', 'refunded', 'active'],
'amount': [100, 200, 300, 150, 500]
})
bad_statuses = ['cancelled', 'refunded']
# Keep all rows NOT in the excluded list
result = df[~df['status'].isin(bad_statuses)]
print(result)
# status amount
# 0 active 100
# 2 shipped 300
# 4 active 500isin() with a DataFrame Column as the List
A powerful trick is to pass the values from another DataFrame's column to isin(). This is equivalent to a SQL semi-join: keep rows in df1 whose key appears in df2. Unlike a full merge, this does not duplicate rows or add extra columns — it just filters.
import pandas as pd
orders = pd.DataFrame({
'order_id': [1, 2, 3, 4, 5],
'revenue': [100, 200, 300, 400, 500]
})
vip_orders = pd.DataFrame({'order_id': [2, 4]})
# Keep orders whose ID appears in vip_orders
result = orders[orders['order_id'].isin(vip_orders['order_id'])]
print(result)
# order_id revenue
# 1 2 200
# 3 4 400The between() Method Overview
between(left, right) returns a boolean Series that is True where the values fall within the closed range [left, right] (inclusive by default). It replaces two-sided conditions like (df['age'] >= 18) & (df['age'] <= 65) with a single, readable call.
The inclusive parameter controls boundary inclusion: 'both' (default), 'left', 'right', or 'neither'.
import pandas as pd
df = pd.DataFrame({
'age': [15, 22, 35, 67, 45, 8]
})
# Select working-age population
result = df[df['age'].between(18, 65)]
print(result)
# age
# 1 22
# 2 35
# 4 45between() with inclusive Parameter
By default, both endpoints are included in the range. Setting inclusive='left' excludes the right boundary (useful for half-open intervals like time bins), inclusive='right' excludes the left, and inclusive='neither' excludes both endpoints for a strict open interval.
import pandas as pd
df = pd.DataFrame({'score': [0, 50, 100, 75, 50]})
# Include only scores strictly between 50 and 100
strict = df[df['score'].between(50, 100, inclusive='neither')]
print(strict)
# score
# 3 75
# Include 50 but not 100
left_closed = df[df['score'].between(50, 100, inclusive='left')]
print(left_closed)
# score
# 1 50
# 3 75
# 4 50between() on Date Columns
between() works on datetime columns too. Pass date strings or Timestamp objects as the boundaries, and Pandas will perform the comparison on the underlying datetime values. This is a clean way to slice a time window without converting dates to integers.
import pandas as pd
df = pd.DataFrame({
'date': pd.to_datetime(['2024-01-01', '2024-06-15', '2024-11-20', '2025-03-01']),
'value': [10, 20, 30, 40]
})
# Filter rows in the year 2024
result = df[df['date'].between('2024-01-01', '2024-12-31')]
print(result)
# date value
# 0 2024-01-01 10
# 1 2024-06-15 20
# 2 2024-11-20 30Combining isin() and between()
You can combine isin() and between() in the same boolean expression using & and |. This creates compact, readable filters that would otherwise require many nested conditions. Always enclose each call in parentheses when combining.
import pandas as pd
df = pd.DataFrame({
'region': ['North', 'South', 'East', 'North', 'West'],
'revenue': [100, 500, 200, 300, 400]
})
# Rows in North or South regions AND revenue between 200 and 400
result = df[
df['region'].isin(['North', 'South']) &
df['revenue'].between(200, 400)
]
print(result)
# region revenue
# 3 North 300
# 1 South 500 <- actually excluded (500 > 400)
# 3 North 300isin() on Multiple Columns with Any
When you want to check if any of several columns contains a value from a list, you can call isin() on the entire DataFrame and use .any(axis=1) to collapse the result row-wise. This is useful for searching across multiple tag or category columns simultaneously.
import pandas as pd
df = pd.DataFrame({
'tag1': ['python', 'java', 'sql'],
'tag2': ['sql', 'python', 'go'],
'topic': ['Database', 'Backend', 'Infra']
})
target_langs = ['python', 'sql']
# Check if either tag column matches
mask = df[['tag1', 'tag2']].isin(target_langs).any(axis=1)
result = df[mask]
print(result)
# tag1 tag2 topic
# 0 python sql Database
# 1 java python Backend
# 2 sql go InfraPerformance Tip: isin() vs Multiple ==
For a small list of 2-3 values, the difference between isin() and chained == conditions is negligible. But for large lists (hundreds of values), isin() is dramatically faster because it converts the list to a hash set internally and performs O(1) look-ups per element rather than sequential comparison.
Always prefer isin() over a long chain of | conditions for cleaner code and better performance.
import pandas as pd
import numpy as np
# 1 million row DataFrame
df = pd.DataFrame({'id': np.random.randint(0, 10000, size=1_000_000)})
allowed = list(range(0, 500)) # 500 allowed IDs
# isin() is the right approach here — fast hash lookup
result = df[df['id'].isin(allowed)]
print(result.shape) # around (50000, 1)Real-World Filter: Product Catalogue
Here is a realistic example combining isin() for category filtering and between() for price range filtering — a common pattern in e-commerce analytics. The two filters together select exactly the product subset needed for a targeted promotion.
import pandas as pd
products = pd.DataFrame({
'name': ['Laptop', 'Mouse', 'Monitor', 'Keyboard', 'Webcam'],
'category': ['Computing', 'Accessories', 'Displays', 'Accessories', 'Peripherals'],
'price': [1200, 25, 300, 80, 150]
})
# Products in Accessories or Peripherals, priced 50-200
eligible = products[
products['category'].isin(['Accessories', 'Peripherals']) &
products['price'].between(50, 200)
]
print(eligible)
# name category price
# 3 Keyboard Accessories 80
# 4 Webcam Peripherals 150Quick Check
Test your understanding of isin() and between() filters.
Lesson Recap
In this lesson you learned: isin() checks set membership and is faster than chaining multiple == conditions, ~isin() excludes a list of values, and between() filters a closed range with an optional inclusive parameter. Both methods work on numeric, string, and datetime columns. Next up we explore how to select DataFrame columns matching a name pattern.
Frequently asked questions
Is the “isin() and between() Filters” lesson free?
Yes — the full text of “isin() and between() Filters” is free to read here on the web, and the Pandas & NumPy Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the Pandas & NumPy Academy course, upgrade to CoddyKit PRO.
What will I learn in “isin() and between() Filters”?
Select rows where a column value is in a list with isin() or within a numeric range with between(). You practise Pandas & NumPy Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.
Do I need any experience to start Pandas & NumPy Academy?
No prior experience is required. Pandas & NumPy Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 3 of 4, so you can start here or from the beginning and move at your own pace.
How long does the “isin() and between() Filters” lesson take?
Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.
Can I write and run code in this Pandas & NumPy Academy lesson?
Yes. Every Pandas & NumPy Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.
All lessons in this course
- Boolean Indexing on DataFrames
- The query() Method
- isin() and between() Filters
- Selecting Columns by Pattern