0
votes

Diviser une colonne de chaîne de dataframe par deux délimiteurs différents

Ce qui suit est mon jeu de données: xxx

Ce qui suit est le code que j'ai essayé d'utiliser xxx

mais il échoue lorsque Il y a une double barre oblique entre première et deuxième élément et échoue également lorsqu'il y a une double barre oblique entre 2 et 3ème élément xxx


1 commentaires

pouvez-vous s'il vous plaît vérifier et confirmer?


3 Réponses :


0
votes

Vous pouvez d'abord remplacer le // par /, puis vous pouvez diviser. Veuillez essayer ce qui suit et faites-nous savoir si cela a fonctionné Entrée

+--------------------+-------+--------------------+------+------+------+
|                 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|
+--------------------+-------+--------------------+------+------+------+

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|
+--------------------+-------+
|DB9450//DB9450/AD...|      a|
|DA0002/DE2396//DF...|      a|
|               HWC72|      a|
|       GG7183/EB6693|      a|
|   TA444/B9X8X4:7-2-|      a|
+--------------------+-------+


2 commentaires

Le: 7-2- n'est pas une valeur fixe. Je dois supprimer tout texte après le dernier délimiteur à la fin de la chaîne, dans ce cas, c'est:


Si vous avez le code article a une valeur fixe: la sous-chaîne peut être utilisée df_b = df_b.withColumn ('col2', df_b ['col2']. Substr (0, 6))



-1
votes

C'est peut-être utile ( spark> = 2.4 ) -

split et La fonction Spark SQL TRANSFORM fera la magie comme ci-dessous-

Charger les données de test fournies

    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  |
      * +------+------+------+
      */

Utiliser split et TRANSFORM (vous pouvez exécuter cette requête directement dans pyspark)

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)
      */


0 commentaires

0
votes

Le traitement du texte en csv fonctionne bien pour cela.

Commençons par lire le texte, en remplaçant les doubles barres obliques inverses en cours de route

Edit: En supprimant également tout après un deux-points

XXX

Obtenez le nombre maximum d'éléments d'affilée pour créer un en-tête approprié

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     |
+---------+-----------+---------+

Ensuite, nous sommes prêts à créer un bloc de données

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

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


0 commentaires