Ce qui suit est mon jeu de données: Ce qui suit est le code que j'ai essayé d'utiliser p> 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 P>
3 Réponses :
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|
+--------------------+-------+
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))
C'est peut-être utile ( spark> = 2.4
) -
split
et La fonction Spark SQL TRANSFORM
fera la magie comme ci-dessous-
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 | * +------+------+------+ */
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) */
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("/")
pouvez-vous s'il vous plaît vérifier et confirmer?