Spark dataframe заменяет нулевые значения для разных типов данных в scala - PullRequest
0 голосов
/ 19 февраля 2020

На аналогичный вопрос есть ответы в SO, но это требование немного отличается. na.fill в Spark DataFrame Scala

У меня есть примерный кадр данных, как показано ниже. Каждый столбец в кадре данных имеет разные типы данных. Таким образом, использование df.na.fill не работает для замены всех нулевых значений.

+-------------------------+-------------------------+-------------------------+
| date                    | id                      | name                    |
+-------------------------+-------------------------+-------------------------+
| 2000-01-01              | NULL                    | ABC                     |
| NULL                    | 123                     | NULL                    |
| NULL                    | NULL                    | CDE                     |
+-------------------------+-------------------------+-------------------------+

Таким образом, независимо от типа данных столбца все NULL должны быть заменены пустой строкой. Число и имя столбцов в кадре данных будут постоянно меняться.

В зависимости от типа данных входного кадра данных следует заменить NULL.

Схема этого кадра данных:

root
 |-- date: timestamp (nullable = false)
 |-- id: integer (nullable = true)
 |-- points_redeemed: string (nullable = false)

Ожидаемый результат:

+-------------------------+-------------------------+-------------------------+
| date                    | id                      | name                    |
+-------------------------+-------------------------+-------------------------+
| 2000-01-01              |                         | ABC                     |
|                         | 123                     |                         |
|                         |                         | CDE                     |
+-------------------------+-------------------------+-------------------------+

Может кто-нибудь посоветовать?

1 Ответ

1 голос
/ 20 февраля 2020

Используйте foldLeft в столбцах данных и проверьте, равно ли это значение literal NULL or .isNull or length(trim(col)) === 0, затем замените на "", иначе значение не изменится.

Example:

import org.apache.spark.sql.functions._
import org.apache.spark.sql.types._
val df= Seq(("2000-01-01","NULL","ABC"),("NULL","123","NULL")).
toDF("date","id","name").
withColumn("date",col("date").cast("timestamp")).
withColumn("id",col("id").cast("int"))

df.printSchema
//root
// |-- date: timestamp (nullable = true)
// |-- id: integer (nullable = true)
// |-- name: string (nullable = true)

df.show()

//+--------------------+----+----+
//|                date|  id|name|
//+--------------------+----+----+
//|2000-01-01 00:00:...|null| ABC|
//|                null| 123|NULL|
//+--------------------+----+----+

#using when otherwise to determine NULL value and replacing with "" if matches.
val df2=df.columns.foldLeft(df)((df, c) => {
  df.withColumn(s"$c",when((lower(col(s"$c")) === lit("null")) || (col(s"$c").isNull)|| (length(trim(col(s"$c"))) === 0),lit("")).otherwise(col(s"$c")))
})

df2.show()
//+-------------------+---+----+
//|               date| id|name|
//+-------------------+---+----+
//|2000-01-01 00:00:00|   | ABC|
//|                   |123|    |
//+-------------------+---+----+

Вы также можете добавить больше проверок, когда выписка при необходимости!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...