A filter is a True/False Series aligned to the index. Put it inside [] or pass it to loc.
Goal
Combine conditions with & | ~, and use isin, between, and query without precedence bugs.
One condition
df = pd.DataFrame(
{
"city": ["Nairobi", "Nairobi", "Mombasa", "Kisumu", "Eldoret"],
"product": ["A", "B", "A", "B", "A"],
"units": [12, 7, 9, 11, 6],
"price": [10.5, 22.0, 10.5, 22.0, 10.5],
}
)
df["revenue"] = df["units"] * df["price"]
print(df[df["units"] >= 9])
print()
print(df.loc[df["city"] == "Nairobi"])Combine with & and |
Python and / or do not work on Series. Use & and |, and parentheses around each comparison.
df = pd.DataFrame(
{
"city": ["Nairobi", "Nairobi", "Mombasa", "Kisumu", "Eldoret"],
"product": ["A", "B", "A", "B", "A"],
"units": [12, 7, 9, 11, 6],
"price": [10.5, 22.0, 10.5, 22.0, 10.5],
}
)
print(df[(df["city"] == "Nairobi") | (df["city"] == "Kisumu")])
print()
print(df[(df["product"] == "A") & (df["units"] >= 9)])
print()
print(df[~(df["product"] == "B")])isin and between
df = pd.DataFrame(
{
"city": ["Nairobi", "Nairobi", "Mombasa", "Kisumu", "Eldoret"],
"product": ["A", "B", "A", "B", "A"],
"units": [12, 7, 9, 11, 6],
"price": [10.5, 22.0, 10.5, 22.0, 10.5],
}
)
print(df[df["city"].isin(["Nairobi", "Mombasa"])])
print()
print(df[df["units"].between(7, 11)])between is inclusive on both ends by default.
query
A string expression. Handy when column names are simple identifiers.
df = pd.DataFrame(
{
"city": ["Nairobi", "Nairobi", "Mombasa", "Kisumu", "Eldoret"],
"product": ["A", "B", "A", "B", "A"],
"units": [12, 7, 9, 11, 6],
"price": [10.5, 22.0, 10.5, 22.0, 10.5],
}
)
print(df.query("units >= 9 and product == 'A'"))
print()
min_units = 8
print(df.query("units >= @min_units"))@min_units pulls in a Python variable.
Filter on a computed column
df = pd.DataFrame(
{
"city": ["Nairobi", "Mombasa", "Kisumu", "Eldoret"],
"product": ["A", "A", "B", "A"],
"units": [12, 9, 11, 6],
"price": [10.5, 10.5, 22.0, 10.5],
}
)
df["revenue"] = df["units"] * df["price"]
print(df[df["revenue"] > 100][["city", "product", "revenue"]])Pitfall
df.units >= 9 & df.product == "A" is parsed as df.units >= (9 & df.product) == "A" and explodes. Always write (df["units"] >= 9) & (df["product"] == "A").