【问题标题】:Pyspark UDF works unless I call any builtin functionsPyspark UDF 工作,除非我调用任何内置函数
【发布时间】:2020-03-13 19:50:21
【问题描述】:

我正在尝试实现一个 pyspark 函数来执行半偶数舍入。问题是如果我简单地返回传入的值,构建工作。如果它做任何其他事情,我会得到一个模糊的错误。这是我的 udf 的工作原理:

@udf(returnType=DecimalType())
def round_half_even(number):
  return number

我只是在数据帧的选择中调用 udf,如下所示:

df1 = spark.read...
df1.select(
    df1.COST,
    round_half_even(f.lit(17.45)).alias('V_COST_TOTAL_CALC')
)

但是这个实际上进行四舍五入的版本失败了:

@udf(returnType=DecimalType())
def round_half_even(number):
  return round(number, 0)

出现此错误:

TypeError: type NoneType doesn't define __round__ method

我对 Python 还是很陌生,所以我真的不知道如何追踪它。好像python环境真的不可用,但这应该是spark的问题而不是我的问题。

编辑:在查看了这个问题后,我意识到 spark 有一个 bround 函数,它可以进行半偶数舍入。我仍然需要解决这个问题,因为我有几个 UDF 都因相同的原因而失败,而这个似乎是最简单的。

更新: 空值检查确实是导致我的 udf 失败的原因,所以我像这样修改它(正如 Hristo Iliev 所建议的那样):

@udf(returnType=DecimalType())
def round_half_even(number):
  return round(number, 0) if number is not None else None

这允许它完成,但现在我得到的只是目标中的空值,即使在上面的示例中传递文字值时也是如此。我已经验证应该有成千上万个非空值。

【问题讨论】:

  • 你能显示udf的电话吗?
  • 您的 udf 失败,因为您没有纠正缺失(SQL 中为 NULL,Python 中为 None)值。
  • 感谢指针 user10938362。如果您可以将其发布为答案而不是评论,我可以接受。
  • if number: 是不好的做法,因为当number0 时,它会导致您的函数返回None(在布尔上下文中,零评估为假)。正确的检查是if number is not None:

标签: python apache-spark pyspark databricks azure-databricks


【解决方案1】:

如果列中有NULL 值,PySpark 会为这些值传递None,而您的round() 函数不会处理None。应该执行以下操作:

@udf(returnType=DecimalType())
def round_half_even(number):
  return round(number, 0) if number is not None else None

注意对非None 值的正确检查是var is not None。整数和浮点零在布尔上下文中的计算结果为 false。

【讨论】:

    【解决方案2】:

    你的参数'number'可能是None,在调用round方法之前先检查一下。

    PS:所有 Python 内置函数都在 PySpark UDF 中可用。如果要调用任何其他方法/库,则必须将其导入 UDF 中。

    【讨论】:

      猜你喜欢
      • 2018-06-17
      • 2021-09-30
      • 2022-06-23
      • 1970-01-01
      • 2020-10-06
      • 2023-04-07
      • 1970-01-01
      • 2019-06-12
      • 2023-03-13
      相关资源
      最近更新 更多