← Назад к вопросам
Что такое LEFT ANTI JOIN в PySpark?
2.0 Middle🔥 191 комментариев
#Big Data и распределенные вычисления#SQL и базы данных
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI30 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
LEFT ANTI JOIN в PySpark
LEFT ANTI JOIN — это операция объединения двух таблиц, которая возвращает все строки из левой таблицы, которые НЕ имеют соответствия в правой таблице.
Синтаксис PySpark
from pyspark.sql import SparkSession
spark = SparkSession.builder.appName("Example").getOrCreate()
# Левая таблица
left_df = spark.createDataFrame([
(1, "Alice"),
(2, "Bob"),
(3, "Charlie"),
(4, "David")
], ["user_id", "name"])
# Правая таблица
right_df = spark.createDataFrame([
(1, "premium"),
(3, "free"),
(5, "admin")
], ["user_id", "plan"])
# LEFT ANTI JOIN
result = left_df.join(right_df, on="user_id", how="leftanti")
result.show()
# +-------+-------+
# |user_id| name|
# +-------+-------+
# | 2| Bob|
# | 4| David|
# +-------+-------+
Почему 2 и 4?
- user_id = 1: есть в правой таблице → исключена
- user_id = 2: НЕТ в правой таблице → ВКЛЮЧЕНА
- user_id = 3: есть в правой таблице → исключена
- user_id = 4: НЕТ в правой таблице → ВКЛЮЧЕНА
Диаграмма
Левая таблица Правая таблица
┌─────┬─────┐ ┌─────┬─────────┐
│ uid │name │ │ uid │ plan │
├─────┼─────┤ ├─────┼─────────┤
│ 1 │Alice│ │ 1 │premium │
│ 2 │ Bob │ │ 3 │ free │
│ 3 │Char │ │ 5 │ admin │
│ 4 │David│ └─────┴─────────┘
└─────┴─────┘
LEFT ANTI JOIN:
┌─────┬─────┐
│ uid │name │ (только строки из левой,
├─────┼─────┤ которых нет в правой)
│ 2 │ Bob │
│ 4 │David│
└─────┴─────┘
Практические примеры
1. Найти пользователей без заказов
users = spark.createDataFrame([
(1, "Alice"),
(2, "Bob"),
(3, "Charlie")
], ["user_id", "name"])
orders = spark.createDataFrame([
(1, 100),
(1, 200),
(3, 300)
], ["user_id", "order_amount"])
# Пользователи БЕЗ заказов
users_no_orders = users.join(orders, on="user_id", how="leftanti")
users_no_orders.show()
# +-------+----+
# |user_id|name|
# +-------+----+
# | 2| Bob|
# +-------+----+
2. Найти товары, которые не были куплены
products = spark.createDataFrame([
("A", 100), ("B", 200), ("C", 300), ("D", 400)
], ["product_id", "price"])
purchases = spark.createDataFrame([
("A",), ("B",), ("C",)
], ["product_id"])
# Товары, которые никто не купил
unpopular = products.join(purchases, on="product_id", how="leftanti")
unpopular.show()
# +----------+-----+
# |product_id|price|
# +----------+-----+
# | D| 400|
# +----------+-----+
3. Найти аномальные транзакции
transactions = spark.createDataFrame([
("T1", 100, "2024-01-01"),
("T2", 200, "2024-01-02"),
("T3", 50, "2024-01-03"),
("T4", 300, "2024-01-04")
], ["transaction_id", "amount", "date"])
legitimate = spark.createDataFrame([
("T1",), ("T2",), ("T4",)
], ["transaction_id"])
# Подозрительные транзакции (не в списке легитимных)
suspicious = transactions.join(
legitimate,
on="transaction_id",
how="leftanti"
)
suspicious.show()
# +----------------+------+----------+
# |transaction_id |amount|date |
# +----------------+------+----------+
# |T3 |50 |2024-01-03|
# +----------------+------+----------+
LEFT ANTI JOIN vs другие JOINs
# Имеем:
left = [(1, 'A'), (2, 'B'), (3, 'C')]
right = [(1, 'X'), (3, 'Y'), (5, 'Z')]
# INNER JOIN
# → [(1, 'A', 'X'), (3, 'C', 'Y')] (только совпадения)
# LEFT JOIN
# → [(1, 'A', 'X'), (2, 'B', None), (3, 'C', 'Y')]
# (все из левой + совпадения)
# LEFT ANTI JOIN
# → [(2, 'B')] (только строки из левой БЕЗ совпадений)
# LEFT SEMI JOIN (похож на ANTI, но без столбцов из правой)
# → [(1, 'A'), (3, 'C')] (строки из левой, У КОТОРЫХ есть совпадения)
Performance примечание
# LEFT ANTI JOIN требует большой памяти на правую таблицу
# Оптимизация: broadcast небольшую правую таблицу
from pyspark.sql.functions import broadcast
result = left_df.join(
broadcast(right_df), # для маленьких таблиц
on="user_id",
how="leftanti"
)
Эквивалент в SQL
-- LEFT ANTI JOIN в PySpark
left_df.join(right_df, on="user_id", how="leftanti")
-- Эквивалент в SQL
SELECT * FROM left_table
WHERE user_id NOT IN (SELECT user_id FROM right_table);
-- или
SELECT left.*
FROM left_table left
LEFT ANTI JOIN right_table right ON left.user_id = right.user_id;
Резюме
LEFT ANTI JOIN:
- Возвращает строки из левой таблицы без совпадений в правой
- Полезен для: поиска отсутствующих данных, исключения записей
- Синтаксис:
df1.join(df2, on=key, how="leftanti") - Отличается от LEFT JOIN (который включает все из левой)
- Эффективнее, чем NOT IN для больших данных