web-dev-qa-db-fra.com

Application de la fonction de mappage sur DataFrame

Je viens de commencer à utiliser databricks/pyspark. J'utilise Python/spark 2.1. J'ai téléchargé des données dans une table. Ce tableau est une colonne unique remplie de chaînes. Je souhaite appliquer une fonction de mappage à chaque élément de la colonne. Je charge la table dans un dataframe:

df = spark.table("mynewtable")

La seule façon dont je pouvais voir, c’est ce que d’autres disaient, c’était de le convertir en RDD pour appliquer la fonction de mappage, puis de nouveau en dataframe pour afficher les données. Mais cela provoque un échec de l'étape de travail annulé:

df2 = df.select("_c0").rdd.flatMap(lambda x: x.append("anything")).toDF()

Tout ce que je veux faire, c'est appliquer n'importe quelle fonction de la carte à mes données dans le tableau. Par exemple, ajoutez quelque chose à chaque chaîne de la colonne, ou effectuez une scission sur un caractère, puis replacez-la dans un cadre de données afin que je puisse .show () ou l'afficher.

13
yahalom

Vous ne pouvez pas:

  • Utilisez flatMap car cela aplatira le Row
  • Vous ne pouvez pas utiliser append car:

    • Tuple ou Row n'a pas de méthode append
    • append (si présent dans la collection) est exécuté pour les effets secondaires et renvoie None

Je voudrais utiliser withColumn:

df.withColumn("foo", lit("anything"))

mais map devrait également fonctionner:

df.select("_c0").rdd.flatMap(lambda x: x + ("anything", )).toDF()

Edit (compte tenu du commentaire):

Vous voulez probablement un udf

from pyspark.sql.functions import udf

def iplookup(s):
    return ... # Some lookup logic

iplookup_udf = udf(iplookup)

df.withColumn("foo", iplookup_udf("c0"))

Le type de retour par défaut est StringType, donc si vous voulez autre chose, vous devriez l'ajuster.

19
hi-zir