从pyspark中的字符串加载jalali日期

eblbsuwk  于 2021-05-19  发布在  Spark
关注(0)|答案(1)|浏览(502)

我需要装货 jalali 从字符串中选择日期,然后作为 gregorian 日期字符串。我使用以下代码:

def jalali_to_gregorian(col, format=None):
    if not format:
        format = "%Y/%m/d"
    gre = jdatetime.datetime.strptime(col, format=format).togregorian()
    return gre.strftime(format=format)

# register the function

spark.udf.register("jalali_to_gregorian", jalali_to_gregorian, StringType())

# load the date and show it:)

df = df.withColumn("financial_date", jalali_to_gregorian(df.PersianCreateDate))
df.select(['PersianCreateDate', 'financial_date']).show()

它抛出 ValueError: time data 'Column<PersianCreateDate>' does not match format '%Y/%m/%d' 我犯了个错误。列中的字符串是匹配的,我已经测试过了。这是spark如何将列值发送到函数的问题。怎么解决呢?
要测试:

df=spark.createDataFrame([('1399/01/02',),('1399/01/01',)],['jalali'])
df = df.withColumn("gre", jalali_to_gregorian(df.jalali))
df.show()

应该导致

+----------+----------+
|    jalali|       gre|
+----------+----------+
|1399/01/02|2020/03/20|
|1399/01/01|2020/03/21|
+----------+----------+

相反,我被扔在:

Fail to execute line 2: df = df.withColumn("financial_date",    jalali_to_gregorian(df.jalali))
Traceback (most recent call last):
File "/tmp/zeppelin_pyspark-6468469233020961307.py", line 375, in <module>
exec(code, _zcUserQueryNameSpace)
File "<stdin>", line 2, in <module>
File "<stdin>", line 7, in jalali_to_gregorian
File "/usr/local/lib/python2.7/dist-packages/jdatetime/__init__.py", line 929, in strptime
(date_string, format))
ValueError: time data 'Column<jalali>' does not match format '%Y/%m/%d''%Y/%m/%d'
6za6bjd0

6za6bjd01#

您的问题是您试图将函数应用于列,而不是应用于列中的值。
您使用的代码: spark.udf.register("jalali_to_gregorian", jalali_to_gregorian, StringType()) 注册您的函数以在sparksql中使用(通过 spark.sql(...) 不是在Pypark。
获取可以在内部使用的函数 withColumn , select 等等,您需要创建一个 Package 器函数 udf 函数和此函数应在 withColumn :

from pyspark.sql.functions import udf
jalali_to_gregorian_udf = udf(jalali_to_gregorian, StringType())
df = df.withColumn("gre", jalali_to_gregorian_udf(df.jalali))
>>> df.show()
+----------+----------+
|    jalali|       gre|
+----------+----------+
|1399/01/02|2020/03/21|
|1399/01/01|2020/03/20|
+----------+----------+

有关详细信息,请参阅文档。
时间格式中也有错误-而不是 format = "%Y/%m/d" 应该是的 format = "%Y/%m/%d" .
p、 如果您运行的是spark 3.x,那么我建议您使用矢量化的UDF(又名pandas UDF)——它们比通常的UDF快得多,如果您有大量数据,它们将提供更好的性能。

相关问题