2
votes

Comment supprimer une sous-chaîne de caractères d'une colonne PySpark Dataframe StringType (), conditionnellement en fonction de la longueur des chaînes dans les colonnes?

J'ai un Dataframe PySpark avec une colonne StringType () qui contient principalement 15 caractères. Cependant, certaines lignes comportent 11 caractères. Exemple:

df.withColumn("code",expr("substring(code, 1, 11)"))

J'ai besoin que toutes les lignes contiennent 11 caractères, les 4 derniers caractères étant supprimés de toute ligne contenant 15 caractères. Voici donc ma sortie souhaitée:

from pyspark.sql.functions import substring, length, col, expr

df = df.withColumn("code",expr("substring(code, 1, length(code)-4)"))

Jusqu'à présent, j'ai cette transformation, qui supprime les 4 derniers caractères de TOUTES les lignes de ma colonne appelée «code»: p>

df.show(8) = 
+-------------+-----+
|         code|state|
+-------------+-----+
|'33444553223'|wa   |
|'33245213223'|mn   |
|'45532234553'|fl   |
|'67964553223'|mo   |
|'91853553223'|ar   |
|'17492553223'|wi   |
|'45532234553'|al   |
|'92840553223'|ca   |
+-------------+-----+

Je dois donc faire quelque chose pour que cela dépende de la longueur de la chaîne dans la ligne.

MODIFIER Avec de l'aide de @gmds, j'ai trouvé cette solution:

df = 
+--------------+--------+
|             code|state|
+--------------+--------+
|'334445532234553'|wa   |
|'332452132234553'|mn   |
|'45532234553'    |fl   |
|'679645532234553'|mo   |
|'918535532234553'|ar   |
|'174925532234553'|wi   |
|'45532234553'    |al   |
|'928405532234553'|ca   |
+--------------+--------+


0 commentaires

3 Réponses :


1
votes

Que diriez-vous de ceci:

df.withColumn('code', df['code'].substr(1, 11))

Votre idée était juste; c'est juste que vous avez fourni une valeur variable pour la longueur de la sous-chaîne, alors que vous vouliez vraiment une constante.


8 commentaires

Je comprends votre idée d'utiliser une constante, mais cela garantit-il que les 4 derniers caractères sont supprimés, selon mes besoins? Comment savoir que cela ne supprimera pas les 4 premiers caractères? Ou, comment l'ajusterais-je si j'avais besoin de supprimer les 4 premiers caractères au lieu des 4 derniers?


Le deuxième paramètre de substr contrôle la longueur de la chaîne. Si vous le réglez sur 11, la fonction prendra (au maximum) les 11 premiers caractères. Ce que vous faites prend tout sauf les 4 derniers caractères. Quant à votre deuxième question, cela dépendra du fait que vous vouliez supprimer les quatre premiers caractères sans discrimination, ou uniquement de ceux de longueur 15.


Merci pour l'explication. Lorsque j'essaie cette solution, j'obtiens un long message d'erreur qui commence: "AnalysisException: u'Resolved attribut (s) codet # 1617 missing from ........" J'ai vérifié et les valeurs de colonne sont définitivement des chaînes.


@TJE C'est bizarre. Essayez F.substring (F.col ('code'), 1, 11) à la place de df ['code']. Substr (1, 11) ?


En fin de compte, voici ce qui a fonctionné (une légère modification de votre code): df.withColumn ("code", expr ("substring (code, 1, 11)")) - Votre suggestion m'a certainement aidé à y arriver.


@TJE Pour clarifier; vous dites que ma suggestion alternative n'a pas fonctionné non plus? C'est assez étrange, pour moi, car je ne peux pas reproduire l'erreur ...


oui, votre suggestion alternative n'a pas fonctionné sur mon système. Si cela fonctionne pour vous, il y a peut-être des différences dans mon environnement ou dans les types de colonnes. Je suis nouveau sur PySpark, donc j'essaie toujours de tout comprendre.


C'est bizarre. Dans tous les cas, si vous avez une réponse à votre question, vous devez la poster et l'accepter!



1
votes

Vous pouvez utiliser la fonction de longueur intégrée avec la sous-chaîne:

from pyspark.sql.functions import substring, length

df = df.withColumn("code", when(length(df.code) > 11, substring(df.code, 1, length(df.code) - 4)).otherwise(df.code))


0 commentaires

0
votes

J'ai trouvé la réponse à ma question en me basant sur les commentaires de @gmds. Le voici:

df.withColumn("code",expr("substring(code, 1, 11)"))

Ce code définit 11 comme une constante, ce qui signifie que si la colonne contient une valeur de 11 ou 15 caractères, après la transformation, ils auront tous la constante de 11 caractères .


0 commentaires