Фильтрация и условные запросы в Pandas
Фильтрация данных — одна из самых распространённых операций в анализе данных. Pandas предоставляет богатый функционал условных запросов, который позволяет фильтровать данные по различным условиям. В этом разделе подробно рассматриваются различные методы фильтрации данных.
Базовая условная фильтрация
Фильтрация по одному условию
Пример
# Создание тестовых данных
df = pd.DataFrame({
"Имя": ["Чжан Сань", "Ли Сы", "Ван У", "Zhao Liu", "Qian Qi"],
"Возраст": [25, 30, 28, 35, 22],
"Город": ["Пекин", "Шанхай", "Гуанчжоу", "Beijing", "Shenzhen"],
"Зарплата": [12000, 15000, 11000, 18000, 9000],
"Department": ["Tech", "Sales", "Tech", "Operations", "Tech"]
})
print(Исходные данные:)
print(df)
print()
# Фильтрация по равенству
print("City equals Beijing:")
print(df[df["City"] == "Beijing"])
print()
# Фильтрация по неравенству
print("Город не равен Пекину:")
print(df[df["City"] != "Beijing"])
print()
# Больше и меньше
print("Зарплата больше 12000:")
print(df[df["Salary"] > 12000])
print()
# Строковое условие
print("Имя содержит 'San':")
print(df[df["Name"].str.contains("San")])
Объединение нескольких условий
Пример
df = pd.DataFrame({
"Имя": ["Чжан Сань", "Ли Сы", "Ван У", "Zhao Liu", "Qian Qi"],
"Возраст": [25, 30, 28, 35, 22],
"Город": ["Пекин", "Шанхай", "Гуанчжоу", "Beijing", "Shenzhen"],
"Зарплата": [12000, 15000, 11000, 18000, 9000],
"Department": ["Tech", "Sales", "Tech", "Operations", "Tech"]
})
# Условие AND: используйте оператор &
print("Пекин и Зарплата>10000:")
print(df[(df["City"] == "Beijing") & (df["Salary"] > 10000)])
print()
# Условие ИЛИ: используйте оператор |
print("Технический отдел или Salary>15000:")
print(df[(df["Department"] == "Tech") | (df["Salary"] > 15000)])
print()
# Условие НЕ: используйте оператор ~
print("Не технический отдел:")
print(df[~(df["Department"] == "Tech")])
print()
# Сложная комбинация
print("(Пекин и Age>25) или (Шанхай):")
print(df[((df["City"] == "Beijing") & (df["Age"] > 25)) | (df["City"] == "Shanghai")])
При объединении нескольких условий каждое условие должно быть заключено в круглые скобки, и используйте
&(И),|(ИЛИ) для соединения, и нельзя использовать в Pythonand、orключевые слова.
isin и where
isin-фильтрация
Пример
df = pd.DataFrame({
"Имя": ["Чжан Сань", "Ли Сы", "Ван У", "Zhao Liu", "Qian Qi"],
"Город": ["Пекин", "Шанхай", "Гуанчжоу", "Beijing", "Shenzhen"],
"Department": ["Tech", "Sales", "Tech", "Operations", "Tech"]
})
# Фильтрация внутри списка
print("Город — Пекин или Шанхай:")
print(df[df["City"].isin(["Beijing", "Shanghai"])])
print()
# Не в списке
print("Город — не Пекин и не Шанхай:")
print(df[~df["City"].isin(["Beijing", "Shanghai"])])
print()
# isin для нескольких столбцов
df2 = pd.DataFrame({
"Город": ["Пекин", "Шанхай"],
"Department": ["Tech", "Sales"]
})
print("Соответствует и городу, и отделу:")
print(df[df[["City", "Department"]].isin(df2).all(axis=1)])
where Condition
Пример
import numpy as np
df = pd.DataFrame({
"A": [1, 5, 3, 7],
"B": [4, 2, 8, 3]
})
# where: сохранять значения, удовлетворяющие условию, остальные устанавливать в NaN или заданное значение
print("Значения больше 3 сохраняются, остальные устанавливаются в 0:")
result = df.where(df > 3, 0)
print(result)
print()
# Использовать другой DataFrame в качестве условия
other = pd.DataFrame({
"A": [True, False, True, False],
"B": [False, True, False, True]
})
print("Фильтрация на основе DataFrame условия:")
print(df.where(other, -1))
Фильтрация строк
Пример
df = pd.DataFrame({
"Имя": ["Чжан Сань", "Ли Сы", "Ван У", "Чжао Лю", "Сунь Ци"],
"Город": ["Пекин", "Шанхай", "Гуанчжоу", "Шэньчжэнь", "Ханчжоу"],
"Email": ["[email protected]", "[email protected]", "[email protected]",
"[email protected]", "[email protected]"]
})
# Содержит
print("Город содержит 'Пекин':")
print(df[df["City"].str.contains("Пекин")])
print()
# Начинается с / Заканчивается на
print("Электронная почта начинается с zhang:")
print(df[df["Email"].str.startswith("zhang")])
print()
# Совпадение регулярного выражения
print("Длина имени пользователя электронной почты больше 4:")
print(df[df["Email"].str.extract(r"(\w+)@")[0].str.len() > 4])
print()
# Сопоставление с несколькими шаблонами
print("Город начинается с Bei, Shang, Guang или Shen:")
print(df[df["City"].str.contains("^Bei|^Shang|^Guang|^Shen")])
Фильтрация по числовому диапазону
Пример
df = pd.DataFrame({
"Имя": ["Чжан Сань", "Ли Сы", "Ван У", "Zhao Liu", "Qian Qi"],
"Возраст": [25, 30, 28, 35, 22],
"Зарплата": [12000, 15000, 11000, 18000, 9000]
})
# Фильтрация диапазона
print("Возраст между 25 и 30 (включительно):")
print(df[df["Age"].between(25, 30)])
print()
# Фильтрация по квантилям
q1 = df["Salary"].quantile(0.25)
q3 = df["Salary"].quantile(0.75)
print(f"Зарплата между 25% и 75% ({q1}-{q3}):")
print(df[df["Salary"].between(q1, q3)])
print()
# Верхние/нижние N строк
print("Топ-3 зарплаты:")
print(df.nlargest(3, "Salary"))
print()
print("2 самые низкие зарплаты:")
print(df.nsmallest(2, "Salary"))
Фильтрация временных данных
Пример
# Создание данных временного ряда
df = pd.DataFrame({
"Date": pd.date_range("2024-01-01", periods=10, freq="D"),
"Sales": [100, 120, 90, 150, 200, 180, 110, 130, 170, 190]
})
df = df.set_index("Date")
print("Данные временного ряда:")
print(df)
print()
# Фильтрация по дате
print("Данные за 2024-01-05:")
print(df.loc["2024-01-05"])
print()
# Фильтрация по диапазону дат
print("С 2024-01-03 по 2024-01-07:")
print(df.loc["2024-01-03":"2024-01-07"])
print()
# Использование truncate (более эффективное срезание)
print("Фильтрация truncate:")
print(df.truncate(before="2024-01-03", after="2024-01-07"))
Метод query
queryМетод обеспечивает более лаконичный подход к фильтрации в стиле SQL.
Пример
df = pd.DataFrame({
"FullName": ["Zhang San", "Li Si", "Wang Wu", "Чжао Лю"],
"Возраст": [25, 30, 28, 35],
"Город": ["Пекин", "Шанхай", "Гуанчжоу", "Пекин"],
"Зарплата": [12000, 15000, 11000, 18000]
})
# Использование метода query
print("Age>26 and City='Beijing':")
print(df.query("Age > 26 and City == 'Beijing'"))
print()
# Использование переменных
min_age = 26
city = "Beijing"
print(f"Age>{min_age} and City={city}:")
print(df.query("Age > @min_age and City == @city"))
print()
# Если в именах столбцов есть пробелы, используйте обратные кавычки
df2 = df.rename(columns={"FullName": "Full Name"})
print("Когда имя столбца содержит пробел:")
print(df2.query("`Full Name` == 'Zhang San'"))
Распространённые проблемы
1. Ошибка при объединении условий
При фильтрации с несколькими условиями используйте скобки для уточнения приоритета и используйте&、|а неand、or。
2. Строки содержат null-значения
Используйтеstr.containsПеред [использованием] необходимо обработать значения null:df[df["列"].str.contains("x", na=False)]
3. Фильтрация по индексу
Если DataFrame имеет пользовательский индекс, обратите внимание наlocиilocразницу.
Другие расширенияДля сложных запросов с несколькими условиями,
queryСинтаксис этого метода ближе к естественному языку, что делает код более читаемым. Когда объём данных большой,locпри объединении с булевыми массивами он обычноqueryбыстрее.