Skip to main content
v2026.11,986 entries · CC-BY 4.0

pandas isin: Series.isin and DataFrame.isin Syntax, Filtering and Pitfalls

How pandas isin filters rows by membership: Series.isin, DataFrame.isin, what each values type aligns on, and common errors.

Written and maintained by CASRAI Editorial Board

Published · Last updated

On this page

pandas isin checks whether each value in a Series or DataFrame appears in a set of values you supply, and returns booleans of the same shape. Use Series.isin(values) to filter rows by membership in a list (for example, keep only participant IDs on an eligibility list), and DataFrame.isin(values) to test every cell at once. The same method is sometimes searched as “isin pandas”; it is the same function. Everything below follows the pandas 3.1.1 reference documentation, read 2026-11-07.

What isin is used for in research

Analysts working in Python use isin to build boolean masks: select the records whose identifier, site code or category is in a list, or exclude them with ~. It answers one question, “is this value one of these values?”, so it is the pandas counterpart of a membership test rather than a join. For creating the DataFrame you are filtering, see how to create a DataFrame in Python.

Install or access

isin is part of pandas, so there is nothing separate to install. The pandas installation page lists pip install pandas and conda install -c conda-forge pandas, and recommends working in a virtual environment (pandas installation guide). Then import pandas as pd.

Step-by-step: filter rows with Series.isin

The signature is Series.isin(values), where values is a set or list-like. It returns a Series of booleans.

  1. Build or load the data. The example below is an illustrative, made-up table of study participants, not real data.
  2. Define the values to match, as a list or set.
  3. Call isin on the column to get the mask, then use the mask to select rows.
  4. Prefix the mask with ~ to select the rows that are not in the list.
import pandas as pd  df = pd.DataFrame({"participant": ["P01", "P02", "P03", "P04"],                    "site": ["A", "B", "A", "C"]}) eligible = ["P01", "P03"]  mask = df["participant"].isin(eligible)   # True, False, True, False df[mask]                                   # rows P01 and P03 df[~mask]                                  # rows P02 and P04

The official documentation shows the same pattern with a Series of animals: s.isin(["cow", "llama"]) returns True for each “cow” or “llama” and False otherwise, and ~s.isin(["cow", "llama"]) negates it.

DataFrame.isin: which values argument aligns on what

DataFrame.isin(values) accepts an iterable, a Series, a DataFrame or a dict and returns a DataFrame of booleans with the same shape. Per the documentation, “the result will only be true at a location if all the labels match.” What must match depends on the type you pass:

Type of values What has to match
List or other iterable Only the cell value is compared; no labels are involved
Series The index labels, as well as the value
dict The keys must be column names, which must match; each column is tested against its own list
DataFrame Both index and column labels must match

The documentation example uses df = pd.DataFrame({"num_legs": [2, 4], "num_wings": [2, 0]}, index=["falcon", "dog"]). df.isin([0, 2]) is True for falcon in both columns and for dog in num_wings; df.isin({"num_wings": [0, 3]}) is True only for dog in num_wings; and when you pass a second DataFrame whose index is ["spider", "falcon"], only the falcon/num_wings cell can be True, because alignment is on both index and columns. The documentation also notes that __iter__, not __contains__, is used to iterate over values.

To test different lists per column, pass a dict, for example df.isin({"site": ["A", "C"]}): only the site column is tested, against that list.

Output and how to read it

The output is always boolean: a Series for Series.isin, a same-shaped DataFrame for DataFrame.isin. True means the value was found in values under the matching rules above. Use the Series result directly as a row filter (df[mask]); a DataFrame result is a cell-by-cell map you can inspect or combine with other boolean operations.

Troubleshooting

TypeError when values is a single string

The Series documentation states that isin raises a TypeError if values is a string. Wrap it in a list: s.isin(["llama"]).

Everything returns False

The documentation notes that strings and integers are not comparable: pd.Series([1]).isin(["1"]) returns False. If IDs were read as numbers in one place and text in another, convert one side so both have the same type before testing.

A DataFrame or Series argument gives unexpected False cells

With a Series or DataFrame as values, labels must match as well as values (see the table above). If you only want to compare values, pass a list instead.

Free alternatives

pandas and NumPy are both free, open-source libraries, so every option here costs nothing. The table compares membership tests that do the same job as isin, using only behaviour stated in each project’s documentation.

Option What it does Documentation
Series.isin(values) Boolean Series for one column; raises TypeError if values is a string pandas.Series.isin
DataFrame.isin(values) Boolean DataFrame, same shape; accepts an iterable, Series, DataFrame or dict pandas.DataFrame.isin
numpy.isin(element, test_elements) Computes element in test_elements element-wise and returns a boolean array with the same shape as element; invert=True returns the complement numpy.isin
DataFrame.query(expr) Filters rows with a string expression; local variables are referenced with @ (for example df.query("A <= @local_var")). Supported operators are documented under eval() pandas.DataFrame.query

For filtering rows by a list of IDs, Series.isin is the direct choice; numpy.isin suits plain arrays that are not in a pandas object.

FAQ

What does pandas isin return?

A Series of booleans for Series.isin and a DataFrame of booleans, same shape as the input, for DataFrame.isin.

How do I select rows that are not in a list?

Negate the mask with ~: df[~df["col"].isin(values)].

Can isin take a dictionary?

Yes, for DataFrame.isin. The keys must be column names that match, and each column is tested against its own list of values.

Is “isin pandas” different from pandas isin?

No. Both searches refer to Series.isin and DataFrame.isin.

Sources

Follow CASRAI

Research-administration guidance, standards updates and independent tool reviews.

Ask CASRAI · free to try

Ask about pandas isin: Series.isin and DataFrame.isin Syntax, Filtering and Pitfalls

Ask your first 2 questions free below. Subscribers get 150 a day for $29 a month.

An AI assistant specialized in research administration. It cites the sources behind every answer, labels web answers and says when it can't answer.

Answers draw on CASRAI's guides and dictionary plus the federal and funder documents we index: Federal Register, Grants.gov, Regulations.gov and UKRI.

Works on this site and inside Claude, Cursor and the AI tools you already use.

Everything CASRAI publishes — this page, the dictionary, the guides and the news — stays free to read, with no account and no card.

Referenced across the research world

University of Cambridge logoColumbia University logoCrossref logoUniversity of Edinburgh logoHarvard University logoUniversity of Oxford logoPrinceton University logoStanford School of Medicine logoUniversity College London logoORCID logoUniversity of Cambridge logoColumbia University logoCrossref logoUniversity of Edinburgh logoHarvard University logoUniversity of Oxford logoPrinceton University logoStanford School of Medicine logoUniversity College London logoORCID logo
  • University of Cambridge logo
  • Columbia University logo
  • Crossref logo
  • University of Edinburgh logo
  • Harvard University logo
  • University of Oxford logo
  • Princeton University logo
  • Stanford School of Medicine logo
  • University College London logo
  • ORCID logo

View CASRAI adoption →