web-dev-qa-db-fra.com

TypeError: L'objet 'Column' n'est pas appelable avec WithColumn

J'aimerais ajouter une nouvelle colonne sur la structure de données "df" de la fonction get_distance:

def get_distance(x, y):
    dfDistPerc = hiveContext.sql("select column3 as column3, \
                                  from tab \
                                  where column1 = '" + x + "' \
                                  and column2 = " + y + " \
                                  limit 1")

    result = dfDistPerc.select("column3").take(1)
    return result

df = df.withColumn(
    "distance",
    lit(get_distance(df["column1"], df["column2"]))
)

Mais je comprends ceci:

TypeError: 'Column' object is not callable

Je pense que cela se produit car x et y sont des objets Column et que je dois être converti en String pour pouvoir être utilisés dans ma requête. Ai-je raison? Si oui, comment puis-je faire cela?

3
Bruno Canal
  • Vous ne pouvez pas utiliser directement la fonction Python sur un objet Column, sauf si elle est conçue pour fonctionner sur des objets/expressions Column Vous avez besoin de udf pour cela:

    @udf
    def get_distance(x, y):
        ...
    
  • Mais vous ne pouvez pas utiliser SQLContext dans udf (ou mappeur en général).

  • Juste join:

    tab = hiveContext.table("tab").groupBy("column1", "column2").agg(first("column3"))
    df.join(tab, ["column1", "column2"])
    
2
user9230621

Spark devrait savoir que la fonction que vous utilisez n’est pas une fonction ordinaire, mais le fichier UDF.

Donc, il y a 2 façons d'utiliser l'UDF sur des cadres de données. 

Méthode 1: avec l'annotation @udf

@udf
def get_distance(x, y):
    dfDistPerc = hiveContext.sql("select column3 as column3, \
                                  from tab \
                                  where column1 = '" + x + "' \
                                  and column2 = " + y + " \
                                  limit 1")

    result = dfDistPerc.select("column3").take(1)
    return result

df = df.withColumn(
    "distance",
    lit(get_distance(df["column1"], df["column2"]))
)

Méthode 2: enregistrement de fichiers PDF avec pyspark.sql.functions.udf

def get_distance(x, y):
    dfDistPerc = hiveContext.sql("select column3 as column3, \
                                  from tab \
                                  where column1 = '" + x + "' \
                                  and column2 = " + y + " \
                                  limit 1")

    result = dfDistPerc.select("column3").take(1)
    return result

calculate_distance_udf = udf(get_distance, IntegerType())

df = df.withColumn(
    "distance",
    lit(calculate_distance_udf(df["column1"], df["column2"]))
)
0
Ajit K'sagar