#scala #apache-spark #sanity-check
#scala #apache-spark #проверка работоспособности
Вопрос:
У меня есть требование выполнить некоторые проверки работоспособности таблицы с использованием Scala.
Мой пример таблицы:
Его можно сгенерировать с помощью следующего кода:
val df = Seq(
(1, "", "13-05-2020", Some("CSE")),
(2, "PQR", "14022019", None),
(3, "XYZ", "25-01-2018", Some(""))
).toDF("ID", "NAME", "Joining Date", "Branch")
Теперь я хочу выполнить проверку Null и проверку даты для всех столбцов. И я хочу, чтобы результат был похож:
Я смог сгенерировать фрейм данных следующим образом:
Пожалуйста, помогите мне заполнить данные в этом DF.
Комментарии:
1. Можете ли вы поделиться кодом, который вы написали до сих пор (как вы генерируете данные, как вы создали этот окончательный df и что вы пытались заполнить)
Ответ №1:
Насколько я понимаю, вы хотите вычислить некоторые общие тесты для всех столбцов фрейма данных.
Также вы, кажется, считаете, что пустая строка ""
похожа на нулевое значение. Поэтому я бы начал с замены пустых строк на значения null (только для столбцов типа string).
import org.apache.spark.sql.types.StringType
val df_with_nulls = df.select(df.schema.fields.map(c =>
if(c.dataType == StringType)
when(col(c.name) === "", null).otherwise(col(c.name)) as c.name
else
col(c.name)
) : _*)
Затем, просто ради более понятного кода, я бы определил одну функцию для каждой проверки, которую вы хотите выполнить. Если они не совсем то, что вы хотите, не стесняйтесь их настраивать:
val name = (c : String) => lit(c) as s"col_list"
val null_check =
(c : String) => sum(col(c).isNull.cast("int")) > 0 as s"Null_check"
val date_pattern = "[0-9]{2}-?[0-9]{2}-?[0-9]{4}"
val date_check =
(c : String) => sum(col(c) rlike date_pattern cast "int") > 0 as s"Date_Check"
val distinct_values = (c : String) => collect_set(col(c)) as "Distinct_Values"
Наконец, вы можете применить их все в общем виде ко всем своим столбцам следующим образом:
df_with_nulls
.select(array(df.columns.map(c =>
struct(name(c), date_check(c), null_check(c), distinct_values(c))
) : _*) as "a")
.select(explode('a) as "s")
.select("s.*")
.show(false)
while выдает то, что вы ожидаете:
------------ ---------- ---------- ----------------------------------
|col_list |Date_Check|Null_check|Distinct_Values |
------------ ---------- ---------- ----------------------------------
|ID |false |false |[1, 2, 3] |
|NAME |false |true |[PQR, XYZ] |
|Joining Date|true |false |[14022019, 13-05-2020, 25-01-2018]|
|Branch |false |true |[CSE] |
------------ ---------- ---------- ----------------------------------
Моим единственным предупреждением было бы не использовать это для столбца со слишком большим количеством различных значений. Действительно, поскольку все они объединены в одну строку, это будет очень медленно или хуже, вызовет исключение ООМ.