Чтобы сделать вещи более конкретными, давайте рассмотрим некоторые игрушечные данные.У нас есть один DataFrame с именем df
, который выглядит следующим образом:
+---+---------+------+------+
| id| city| col1| col2|
+---+---------+------+------+
|100|Frankfurt|filler|filler|
|200| Berlin|filler|filler|
|100| Vienna|filler|filler|
|500| Victoria|filler|filler|
|600| Shanghai|filler|filler|
|100| Cologne|filler|filler|
+---+---------+------+------+
и другой, с именем cities
, который выглядит следующим образом:
+---------+
| cityName|
+---------+
|Frankfurt|
| Vienna|
+---------+
Мы можем выполнить ваши запросынапример:
val cityList = cities.collect.map(x => x(0))
val df1 = df.withColumn("col1", when($"id" === "100" and $"city".isin(cityList: _*), "yes"))
Результат, который мы получаем:
+---+---------+----+------+
| id| city|col1| col2|
+---+---------+----+------+
|100|Frankfurt| yes|filler|
|200| Berlin|null|filler|
|100| Vienna| yes|filler|
|500| Victoria|null|filler|
|600| Shanghai|null|filler|
|100| Cologne|null|filler|
+---+---------+----+------+
Для вашего второго запроса мы используем такие же cityList
:
val df2 = df.withColumn("col2", when($"id" === "100" and !$"city".isin(cityList: _*), "yes"))
us
+---+---------+------+----+
| id| city| col1|col2|
+---+---------+------+----+
|100|Frankfurt|filler|null|
|200| Berlin|filler|null|
|100| Vienna|filler|null|
|500| Victoria|filler|null|
|600| Shanghai|filler|null|
|100| Cologne|filler| yes|
+---+---------+------+----+
Тем не менее, есть большой недостаток в этом подходе.Если количество городов велико, вам может не хватить памяти, собрав все названия.Вместо этого я хотел бы рассмотреть альтернативный подход, такой как внешнее соединение:
df.join(cities, df("city") === cities("cityName"), "outer").
withColumn("col1", when($"cityName".isNotNull and $"id" === "100", "yes")).
withColumn("col2", when($"cityName".isNull and $"id" === "100", "yes")).
drop("cityName")
, дающий нам
+---+---------+----+----+
| id| city|col1|col2|
+---+---------+----+----+
|100|Frankfurt| yes|null|
|500| Victoria|null|null|
|200| Berlin|null|null|
|100| Vienna| yes|null|
|100| Cologne|null| yes|
|600| Shanghai|null|null|
+---+---------+----+----+
Да, он вводит дополнительный столбец, но только временно, и избегаетпотянув потенциально большой список городов в память водителя.