我有一个数据帧,我正在尝试根据某个日期的end_date
筛选它是>=
还是<
。
然而,我得到了一个";不可调用";错误
line 148, in <module>
df_s1 = df_x.filter(df_x["end_date"].ge(lit("2022-08-17")))
TypeError: 'Column' object is not callable"
这是我的代码:
df_x = df_x.join(df_di_meet, trim(df_x.application_id) == trim(df_di_meet.application_id), "left")
.select (df_x["*"], df_di_meet["end_date"])
# ... Cast end_date to timestamp ...end_date format looks like 2013-12-20 23:59:00.0000000
df_x = df_x.withColumn("end_date",(col("end_date").cast("timestamp")))
# ... Here df_s1 >= 2022-08-17
df_s1 = df_x.filter(df_x["end_date"].ge(lit("2022-08-17")))
#... Here df_s2 < 2022-08-17
df_s2 = df_x.filter(df_x["end_date"].lt(lit("2022-08-17")))
我想做的是检查其他逻辑,就像下面的代码一样,但由于它不适用于when
子句,我决定分解数据帧,并分别检查每个数据帧。有没有更简单的方法,或者我如何让下面的代码工作?
df_x = df_x.withColumn("REV_STAT_TYP_DES", when((df_x.review_statmnt_type_desc == lit("")) & (df_x("end_date").ge(lit("2022-08-17"))), "Not Released")
when((df_x.review_statmnt_type_desc == lit("")) & ((df_x("end_date").lt(lit("2022-08-17"))) | (df_x.end_date == lit(""))), "Not Available")
.otherwise(None))
有人试图让困难的代码看起来更干净。根据这些建议,如果将条件语句分为不同的变量,则可以更好地理解和维护这些条件语句。看看我是如何将isnull
添加到一些变量中的——如果不将它们重构为单独的变量,这将更加困难。
from pyspark.sql import functions as F
no_review = (F.col("review_statmnt_type_desc") == "") | F.isnull("review_statmnt_type_desc")
no_end_date = (F.col("end_date") == "") | F.isnull("end_date")
not_released = no_review & (F.col("end_date") >= F.lit("2022-08-17"))
not_available = no_review & ((F.col("end_date") < F.lit("2022-08-17")) | no_end_date)
此外,如果otherwise
子句返回null
(默认行为(,则不需要它。
df_x = df_x.withColumn(
"REV_STAT_TYP_DES",
F.when(not_released, "Not Released")
.when(not_available, "Not Available")
)
df_x("end_date"(-->这是访问spark数据帧列的错误方式。这就是为什么python假设它是可调用的,而您却得到了这个错误。
df_x["end_date"]->这就是访问列(或df_x.end_date(的方式
更新:
现在只注意到,.ge((或.le((类型的方法不适用于spark数据帧列对象。您可以使用以下任何一种过滤方式:
from pyspark.sql.functions import col
df_s1 = df_x.filter(df_x["end_date"] >='2022-08-17')
# OR
df_s1 = df_x.filter(df_x.end_date>='2022-08-17')
# OR
df_s1 = df_x.filter(col('end_date')>='2022-08-17')
# OR
df_s1 = df_x.filter("end_date>='2022-08-17'")
# OR
# you can use df_x.where() instead of df_x.filter
您可能混淆了panda和pyspark。不管怎样,就是这样做的
DataFrame
df=spark.createDataFrame([("2022-08-16",1),("2019-06-24",2),("2022-08-19",3)]).toDF("date","increment")#
Pyspark
df_x = df.withColumn('date', to_date('date'))
df_x.filter(col('date')>(to_date(lit("2022-08-17")))).show()
Pandas
df_x = df.toPandas()
df_s1 = df_x.assign(date= pd.to_datetime(df_x['date'])).query("date.gt('2022-08-17')", engine='python')
或
df_x[df_x['date']>'2022-08-17']
在expr((函数中使用SQL风格的自由形式case/when语法。这样它也是可移植的。
df_x = (df_x.withColumn("REV_STAT_TYP_DES",
expr(""" case
when review_statmnt_type_desc='' and end_date >='2022-08-17' then 'Not Released'
when review_statmnt_type_desc='' and ( end_date <'2022-08-17' or end_date is null ) then 'Not Available'
else null
end
""")