web-dev-qa-db-fra.com

PySpark: TypeError: la condition doit être une chaîne ou une colonne.

J'essaye de filtrer un RDD basé comme ci-dessous:

spark_df = sc.createDataFrame(pandas_df)
spark_df.filter(lambda r: str(r['target']).startswith('good'))
spark_df.take(5)

Mais j'ai eu les erreurs suivantes:

TypeErrorTraceback (most recent call last)
<ipython-input-8-86cfb363dd8b> in <module>()
      1 spark_df = sc.createDataFrame(pandas_df)
----> 2 spark_df.filter(lambda r: str(r['target']).startswith('good'))
      3 spark_df.take(5)

/usr/local/spark-latest/python/pyspark/sql/dataframe.py in filter(self, condition)
    904             jdf = self._jdf.filter(condition._jc)
    905         else:
--> 906             raise TypeError("condition should be string or Column")
    907         return DataFrame(jdf, self.sql_ctx)
    908 

TypeError: condition should be string or Column

Une idée de ce que j'ai manqué? Je vous remercie!

8
Edamame

DataFrame.filter, qui est un alias pour DataFrame.where, attend une expression SQL exprimée sous la forme Column:

spark_df.filter(col("target").like("good%"))

ou une chaîne SQL équivalente:

spark_df.filter("target LIKE 'good%'")

Je crois que vous essayez ici d'utiliser RDD.filter qui est une méthode complètement différente:

spark_df.rdd.filter(lambda r: r['target'].startswith('good'))

et ne bénéficie pas des optimisations SQL.

21
user6910411

Je suis passé par là et je me suis mis à utiliser un fichier UDF:

from pyspark.sql.functions import udf
from pyspark.sql.types import BooleanType

filtered_df = spark_df.filter(udf(lambda target: target.startswith('good'), 
                                  BooleanType())(spark_df.target))

Plus lisible serait d’utiliser une définition de fonction normale au lieu de la lambda

4
architectonic

convertir le dataframe en rdd. 

spark_df = sc.createDataFrame(pandas_df)
spark_df.rdd.filter(lambda r: str(r['target']).startswith('good'))
spark_df.take(5)

Je pense que ça peut marcher!

0
Ashok v