编辑:我不认为它是重复的,因为我不是在尝试在数据帧中合并数据,而是要获取int(或字符串)值以字符串格式使用它。用concat_ws处理的简单串联无法解决问题,因为“ 96-3-12”不会被解释为日期。我必须将其转换为1996-03-12或获取int值,以将其传递给datetime.date函数,然后应用datefiff函数。
我正在尝试在pyspark中查询数据集,并从出生月份和出生年份计算出近似年龄
from pyspark.sql.types import IntegerType
presc_par_med = med.join(presc.groupBy(presc.chaiprat).agg(F.sum(presc.nbmol).alias("nb_mol"), \
F.count(presc.nbmol).alias("nb_presc"), \
F.countDistinct(presc.numano).alias("nb_pat"), \
F.datediff(F.current_date(), "%d-%d-15" % (med.year.cast(IntegerType()), med.month.cast(IntegerType()))).alias("age")), \
med.pranum == presc.chaiprat)
但是当我执行此操作时,我有一个错误
TypeError: %d format: a number is required, not Column
这不是演员的角色吗? 我尝试了%s,却遇到了另一个错误。
编辑:不同尝试,考虑答案和评论(并修改原始的查询,但无论如何还是错误的):
1。尝试使用concat_ws函数计算出生日期。
presc_par_med = med.withColumn("age", F.datediff(F.current_date(), \
F.concat_ws("-", med.year, med.month, F.lit("15")))) \
.withColumn("birthdate", F.concat_ws("-", med.year, med.month, F.lit("15"))) \
.join(presc.groupBy(presc.chaiprat) \
.agg(F.sum(presc.nbmol).alias("nb_mol"), \
F.count(presc.nbmol).alias("nb_presc"), \
F.countDistinct(presc.numano).alias("nb_pat")), \
med.pranum == presc.chaiprat)
输出为我们提供了
[Row(id=94, year=52, month=3, [...], age=None, birthdate=u'52-3-15', [...], nb_mol=14514, nb_presc=3624, nb_pat=520)]
日期已正确连接,但由于格式错误,年龄为“无”。 当我尝试修改年份和月份以完成世纪和.zfill(2)时,我遇到了与以前相同的问题:我无法达到任何整数或字符串值...
2。尝试使用生日日期功能以获取正确的日期
from pyspark.sql.types import IntegerType
from pyspark.sql.functions import udf
import datetime
@udf("date")
def birthdate(year, month, day):
return datetime.date(year, month, day)
presc_par_med = med.withColumn("age", F.datediff(F.current_date(), \
F.concat_ws("-", med.year, med.month, F.lit("15")))) \
.withColumn("birthdate", birthdate(med.year.cast("int"), med.month.cast("int"), 15)) \
.join(presc.groupBy(presc.chaiprat) \
.agg(F.sum(presc.nbmol).alias("nb_mol"), \
F.count(presc.nbmol).alias("nb_presc"), \
F.countDistinct(presc.numano).alias("nb_pat")), \
med.pranum == presc.chaiprat)
我遇到了错误错误:
---> 12 presc_par_med = ...
[...]
Py4JError: An error occurred while calling z:org.apache.spark.sql.functions.col. Trace:
py4j.Py4JException: Method col([class java.lang.Integer]) does not exist
at py4j.reflection.ReflectionEngine.getMethod(ReflectionEngine.java:318)
at py4j.reflection.ReflectionEngine.getMethod(ReflectionEngine.java:339)
3。为功能点亮
from pyspark.sql.types import IntegerType
from pyspark.sql.functions import udf
import datetime
@udf("date")
def birthdate(year, month, day):
return datetime.date(year, month, day)
presc_par_med = med.withColumn("age", F.datediff(F.current_date(), \
F.concat_ws("-", med.year, med.month, F.lit("15")))) \
.withColumn("birthdate", birthdate(med.year.cast("integer"), med.month.cast("integer"), F.lit(15))) \
.join(presc.groupBy(presc.chaiprat) \
.agg(F.sum(presc.nbmol).alias("nb_mol"), \
F.countDistinct(presc.numano).alias("nb_pat")), \
med.pranum == presc.chaiprat)
presc_par_med.take(1)
错误:
Py4JJavaError: An error occurred while calling o2126.collectToPython.
: org.apache.spark.SparkException: Exception thrown in awaitResult:
at org.apache.spark.util.ThreadUtils$.awaitResult(ThreadUtils.scala:205)
[...]
File "/usr/lib/spark/python/pyspark/worker.py", line 104, in <lambda>
func = lambda _, it: map(mapper, it)
File "<string>", line 1, in <lambda>
File "/usr/lib/spark/python/pyspark/worker.py", line 69, in <lambda>
return lambda *a: toInternal(f(*a))
File "<ipython-input-90-1cbfa91d0947>", line 10, in datenaiss
TypeError: an integer is required
答案 0 :(得分:1)
Column
表达式表示逻辑执行计划而不是值的转换。强制转换没有什么不同-将一个表达式映射到另一个表达式。
要使用普通的Python函数对值进行运算,可以使用udf
:
from pyspark.sql.functions import udf
@udf("string")
def fifteenth(year, month):
return "%d-%d-15" % (year, month)
或
import datetime
@udf("date")
def fifteenth(year, month):
return datetime.date(year, month, 15)
并将其用作
F.datediff(
F.current_date(),
fifteenth(med.year.cast("integer"), med.month.cast("integer"))
)
但是你真的不应该。最好:
from pyspark.sql.functions.import concat_ws, lit
concat_ws("-", med.year, med.month, lit("15"))