Заполните DataFrame значениями, указанными на карте - PullRequest
1 голос
/ 29 октября 2019

Моя цель - создать функцию, которая принимает Карту и фрейм данных в качестве параметра:

fillNa (columnsToFill, originalDF)

может заполнить фрейм данныхсо значениями, указанными на карте.

Я работаю с фреймом данных, похожим на тот, который вы видите ниже:

+---------+-------------+----------------+-------------------+
|seller_id|     nickname|successful_items|power_seller_status|
+---------+-------------+----------------+-------------------+
|260341211|HEBICOTE62617|              15|               null|
|269984665|VACAPERVIAJES|              12|               null|
|223499446|GAFAOCOSSR005|              10|               gold|
|265004480|NEFCOTEOC8179|            null|             silver|
|265200651|RUBENTARARIRA|              11|               null|
+---------+-------------+----------------+-------------------+

Таким образом, желаемым результатом является следующее:

+---------+-------------+----------------+-------------------+
|seller_id|     nickname|successful_items|power_seller_status|
+---------+-------------+----------------+-------------------+
|260341211|HEBICOTE62617|              15|             normal|
|269984665|VACAPERVIAJES|              12|             normal|
|223499446|GAFAOCOSSR005|              10|               gold|
|265004480|NEFCOTEOC8179|               0|             silver|
|265200651|RUBENTARARIRA|              11|             normal|
+---------+-------------+----------------+-------------------+

Код, который генерирует DataFrame, следующий:

val someData = Seq(
    Row("260341211", "HEBICOTE62617", 15,   null),
    Row("269984665", "VACAPERVIAJES", 12,   null),
    Row("223499446", "GAFAOCOSSR005", 10,   "gold"),
    Row("265004480", "NEFCOTEOC8179", null, "silver"),
    Row("265200651", "RUBENTARARIRA", 11,   null)
)

val someSchema = List(
  StructField("seller_id", StringType, true),
  StructField("nickname",   StringType, true),
  StructField("successful_items", IntegerType, true),
  StructField("power_seller_status",   StringType, true)
)

val originalDF = spark.createDataFrame(
  spark.sparkContext.parallelize(someData),
  StructType(someSchema)
)

Однако, когда я попытался создать функцию, которая принимает строку и заполняет значения, я не могу сделатьэто для обоих полей. Лучшее, что я могу сделать:

1- Заменить только один столбец
2- Дублировать строки

Карта, используемая в качестве параметра, выглядит следующим образом:

 val columnsToFill = Map("power_seller_status" -> "normal",
                               "successful_items" -> "0")

Функции, которые я создал:

Версия 1

def fillNa_version1(replacements: Map[String, String], dataFrame: DataFrame): DataFrame = {
   dataFrame.na.fill(replacements.values.head, Seq(replacements.keys.head))
}

Версия 2

 def fillNa_version2(replacements: Map[String, String], dataFrame: DataFrame)= {
  replacements.map{keyVal => dataFrame.na.fill(keyVal._2, Seq(keyVal._1))}.reduce(_.union(_))
 }

Ответы [ 2 ]

1 голос
/ 29 октября 2019
originalDF.na.fill(columnsToFill).show()

выход:

+---------+-------------+----------------+-------------------+
|seller_id|     nickname|successful_items|power_seller_status|
+---------+-------------+----------------+-------------------+
|260341211|HEBICOTE62617|              15|             normal|
|269984665|VACAPERVIAJES|              12|             normal|
|223499446|GAFAOCOSSR005|              10|               gold|
|265004480|NEFCOTEOC8179|               0|             silver|
|265200651|RUBENTARARIRA|              11|             normal|
+---------+-------------+----------------+-------------------+

что, кажется, то, что вы хотите, нет?

0 голосов
/ 29 октября 2019

Если все, что вы хотите сделать, это заменить свои пустые значения каким-либо значением по умолчанию, есть гораздо более простые способы сделать это. Вы можете использовать withColumn для получения нового столбца.

originalDF.select(
$"seller_id",
$"nickname",
$"successful_items",
$"power_seller_status").
withColumn("derived_successful_items", when($"successful_items".isNull,"0").otherwise($"successful_items")).
withColumn("derived_power_seller",when ($"power_seller_status".isNull,"normal").otherwise($"power_seller_status")).show

Вы также можете использовать coalesce (возвращает первый ненулевой аргумент):

withColumn("coalesced_successful_items",coalesce($"successful_items",lit("0")))
...