web-dev-qa-db-ja.com

PySpark:TypeError:条件は文字列または列である必要があります

以下のように基づいてRDDをフィルタリングしようとしています:

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

しかし、次のエラーが発生しました:

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

私が見逃したものはありますか?ありがとうございました!

15
Edamame

DataFrame.filterは、DataFrame.whereのエイリアスであり、Columnとして表現されるSQL式を期待します。

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

または同等のSQL文字列:

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

ここではRDD.filterを使用しようとしていると思いますが、これはまったく別の方法です。

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

sQL最適化のメリットはありません。

29
zero323

私はこれを経験し、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))

より読みやすくするには、ラムダの代わりに通常の関数定義を使用します

4
architectonic

データフレームをrddに変換します。

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

うまくいくと思います!

0
Ashok v