Разделить столбец строки фрейма данных на два разных разделителя - PullRequest
0 голосов
/ 10 июля 2020

Вот мой набор данных:

Itemcode

DB9450//DB9450/AD9066

DA0002/DE2396//DF2345

HWC72

GG7183/EB6693

TA444/B9X8X4:7-2-

Ниже приведен код, который я пытался использовать

df.withColumn("item1", split(col("Itemcode"), "/").getItem(0)).withColumn("item2", split(col("Itemcode"), "/").getItem(1)).withColumn("item3", split(col("Itemcode"), "//").getItem(0))

Но он терпит неудачу, когда есть двойной sla sh между первым и вторым элементом, а также не удается, когда есть двойной sla sh между 2-м и 3-м элементом

Desired output is:

  item1    item2     item3

DB9450 DB9450 AD9066

DA0002 DE2396 DF2345

HWC72

GG7183 EB6693

TA444  B9X8X4

Ответы [ 3 ]

0 голосов
/ 10 июля 2020

Возможно, это полезно (spark>=2.4) -

split и TRANSFORM spark sql функция будет выполните magi c, как показано ниже -

Загрузите предоставленные тестовые данные

val data =
      """
        |Itemcode
        |
        |DB9450//DB9450/AD9066
        |
        |DA0002/DE2396//DF2345
        |
        |HWC72
        |
        |GG7183/EB6693
        |
        |TA444/B9X8X4:7-2-
      """.stripMargin
    val stringDS = data.split(System.lineSeparator())
      .map(_.split("\\|").map(_.replaceAll("""^[ \t]+|[ \t]+$""", "")).mkString("|"))
      .toSeq.toDS()
    val df = spark.read
      .option("sep", "|")
      .option("inferSchema", "true")
      .option("header", "true")
      .option("nullValue", "null")
      .csv(stringDS)
    df.show(false)
    df.printSchema()

    /**
      * +---------------------+
      * |Itemcode             |
      * +---------------------+
      * |DB9450//DB9450/AD9066|
      * |DA0002/DE2396//DF2345|
      * |HWC72                |
      * |GG7183/EB6693        |
      * |TA444/B9X8X4:7-2-    |
      * +---------------------+
      *
      * root
      * |-- Itemcode: string (nullable = true)
      */

Используйте split и TRANSFORM (вы можете запустить этот запрос непосредственно в pyspark)

    df.withColumn("item_code", expr("TRANSFORM(split(Itemcode, '/+'), x -> split(x, ':')[0])"))
      .selectExpr("item_code[0] item1", "item_code[1] item2", "item_code[2] item3")
      .show(false)

    /**
      * +------+------+------+
      * |item1 |item2 |item3 |
      * +------+------+------+
      * |DB9450|DB9450|AD9066|
      * |DA0002|DE2396|DF2345|
      * |HWC72 |null  |null  |
      * |GG7183|EB6693|null  |
      * |TA444 |B9X8X4|null  |
      * +------+------+------+
      */
0 голосов
/ 11 июля 2020

Для этого хорошо работает обработка текста как csv.

Во-первых, давайте прочитаем текст, заменяя двойные обратные косые черты по пути

Изменить: также удалить все после двоеточия

val items = """
Itemcode

DB9450//DB9450/AD9066

DA0002/DE2396//DF2345

HWC72

GG7183/EB6693

TA444/B9X8X4:7-2-

""".replaceAll("//", "/").split(":")(0)

Получить максимальное количество элементов в строке, чтобы создать соответствующий заголовок

val numItems = items.split("\n").map(_.split("/").size).reduce(_ max _)

val header = (1 to numItems).map("Itemcode" + _).mkString("/")

Затем мы готовы создать фрейм данных

val df = spark.read
  .option("ignoreTrailingWhiteSpace", "true")
  .option("delimiter", "/")
  .option("header", "true")
  .csv(spark.sparkContext.parallelize((header + items).split("\n")).toDS)
  .filter("Itemcode1 <> 'Itemcode'")

df.show(false)


+---------+-----------+---------+
|Itemcode1|Itemcode2  |Itemcode3|
+---------+-----------+---------+
|DB9450   |DB9450     |AD9066   |
|DA0002   |DE2396     |DF2345   |
|HWC72    |null       |null     |
|GG7183   |EB6693     |null     |
|TA444    |B9X8X4     |null     |
+---------+-----------+---------+
0 голосов
/ 10 июля 2020

Сначала вы можете заменить // на /, а затем разделить. Попробуйте выполнить приведенное ниже и сообщите нам, сработало ли оно Введите

df_b = spark.createDataFrame([('DB9450//DB9450/AD9066',"a"),('DA0002/DE2396//DF2345',"a"),('HWC72',"a"),('GG7183/EB6693',"a"),('TA444/B9X8X4:7-2-',"a")],[ "reg","postime"])
+--------------------+-------+
|                 reg|postime|
+--------------------+-------+
|DB9450//DB9450/AD...|      a|
|DA0002/DE2396//DF...|      a|
|               HWC72|      a|
|       GG7183/EB6693|      a|
|   TA444/B9X8X4:7-2-|      a|
+--------------------+-------+

Logi c

df_b = df_b.withColumn('split_col', F.regexp_replace(F.col('reg'), "//", "/"))
df_b = df_b.withColumn('split_col', F.split(df_b['split_col'], '/'))
df_b = df_b.withColumn('col1' , F.col('split_col').getItem(0))
df_b = df_b.withColumn('col2' , F.col('split_col').getItem(1))
df_b = df_b.withColumn('col2', F.regexp_replace(F.col('col2'), ":7-2-", ""))
df_b = df_b.withColumn('col3' , F.col('split_col').getItem(2))

Выход

+--------------------+-------+--------------------+------+------+------+
|                 reg|postime|           split_col|  col1|  col2|  col3|
+--------------------+-------+--------------------+------+------+------+
|DB9450//DB9450/AD...|      a|[DB9450, DB9450, ...|DB9450|DB9450|AD9066|
|DA0002/DE2396//DF...|      a|[DA0002, DE2396, ...|DA0002|DE2396|DF2345|
|               HWC72|      a|             [HWC72]| HWC72|  null|  null|
|       GG7183/EB6693|      a|    [GG7183, EB6693]|GG7183|EB6693|  null|
|   TA444/B9X8X4:7-2-|      a|[TA444, B9X8X4:7-2-]| TA444|B9X8X4|  null|
+--------------------+-------+--------------------+------+------+------+
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...