#scala #apache-spark
#scala #apache-spark
Вопрос:
Привет, как дела? Вот мои два фрейма данных:
val id_df = Seq(("1","gender"),("2","city"),("3","state"),("4","age")).toDF("id","type")
val main_df = Seq(("male","los angeles","null"),("female","new york","new york")).toDF("1","2","3")
Вот как они выглядят в табличной форме:
и это то, что я хотел бы, чтобы результирующий фрейм данных выглядел так:
Я хочу проверить все идентификаторы в id_df, если они существуют в столбцах main_df, а затем проверить, все ли значения идентификаторов для этой строки не равны null. Если все они не равны null, то мы помещаем «true» в столбец «соответствует условию» для этой строки, в противном случае мы помещаем «false». Обратите внимание, что идентификационный номер 4 для age отсутствует в столбцах main_df, поэтому мы просто игнорируем его.
Как мне это сделать?
Большое спасибо и хорошего дня.
Ответ №1:
Позвольте мне начать с двух коротких наблюдений:
- Я считаю, что было бы безопаснее избегать именования наших столбцов одиночными числами. Подумайте о случае, когда нам нужно вычислить выражение
1 is not null
. Здесь неоднозначно, имеем ли мы в видуcolumn 1
илиvalue 1
само. - Насколько мне известно, хранить и обрабатывать целевые столбцы через фрейм данных неэффективно. Это создало бы накладные расходы, которых можно легко избежать, используя единую коллекцию scala, т.е. Seq, Array, Set и т. Д.
И вот решение вашей проблемы:
import org.apache.spark.sql.functions.col
val id_df = Seq(
("c1","gender"),
("c2","city"),
("c3","state"),
("c4","age")
).toDF("id","type")
val main_df = Seq(
("male", "los angeles", null),
("female", "new york", "new york"),
("trans", null, "new york")
).toDF("c1","c2","c3")
val targetCols = id_df.collect()
.map{_.getString(0)} //get id
.toSet //convert current sequence to a set (required for the intersection)
.intersect(main_df.columns.toSet) //get common columns with main_df
.map(col(_).isNotNull) //convert c1,..cN to col(c[i]).isNotNull
.reduce(_ amp;amp; _) // apply the AND operator between items
// (((c1 IS NOT NULL) AND (c2 IS NOT NULL)) AND (c3 IS NOT NULL))
main_df.withColumn("meets_conditions", targetCols).show(false)
// ------ ----------- -------- ----------------
// |c1 |c2 |c3 |meets_conditions|
// ------ ----------- -------- ----------------
// |male |los angeles|null |false |
// |female|new york |new york|true |
// |trans |null |new york|false |
// ------ ----------- -------- ----------------
Комментарии:
1. позвольте мне повторить вопрос, потому что я не совсем понимаю ваш ответ