我需要装货 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'
1条答案
按热度按时间6za6bjd01#
您的问题是您试图将函数应用于列,而不是应用于列中的值。
您使用的代码:
spark.udf.register("jalali_to_gregorian", jalali_to_gregorian, StringType())
注册您的函数以在sparksql中使用(通过spark.sql(...)
不是在Pypark。获取可以在内部使用的函数
withColumn
,select
等等,您需要创建一个 Package 器函数udf
函数和此函数应在withColumn
:有关详细信息,请参阅文档。
时间格式中也有错误-而不是
format = "%Y/%m/d"
应该是的format = "%Y/%m/%d"
.p、 如果您运行的是spark 3.x,那么我建议您使用矢量化的UDF(又名pandas UDF)——它们比通常的UDF快得多,如果您有大量数据,它们将提供更好的性能。