在PySpark中使用udf时,我们必须在创建udf时声明操作的返回类型。

现在考虑一个场景,我有两列,然后将它们添加到第三列。我使用以下方法将它们加起来

>>> udf_add  = udf(lambda x: x[0]+x[1], IntegerType())
>>> spark.createDataFrame([(101, 1, 16)], ['ID', 'A', 'B']).withColumn('Result', udf_add(array('A', 'B'))).show()
+---+---+---+------+
| ID|  A|  B|Result|
+---+---+---+------+
|101|  1| 16|    17|
+---+---+---+------+


现在假设其中一列是浮点数,我执行相同的操作

>>> spark.createDataFrame([(101, 1, 16.1)], ['ID', 'A', 'B']).withColumn('Result', udf_add(array('A', 'B'))).show()

+---+---+----+------+
| ID|  A|   B|Result|
+---+---+----+------+
|101|  1|16.1|  null|
+---+---+----+------+


在这种情况下,我得到一个空值,因为我的结果实际上是一个浮点数,但是我已经向udf提到它会是一个浮点数。为了克服这个问题,我将我的udf更改为FloatType以解决所有情况

>>> udf_add = udf(lambda x: x[0] + x[1], FloatType())


但是,当我将整数值传递给它时,它将返回null值。

>>> spark.createDataFrame([(101, 1, 16)], ['ID', 'A', 'B']).withColumn('Result', udf_add(array('A', 'B'))).show()

+---+---+---+------+
| ID|  A|  B|Result|
+---+---+---+------+
|101|  1| 16|  null|
+---+---+---+------+


所以问题是-pyspark中是否存在包含整数和浮点数的数据类型,并且可以处理上述两种情况?

如果不是,是否有办法事先确定或不定义数据类型?

我之所以这样问,是因为我有多个数据集,并且希望对它们执行同一组操作。值可以是整数或浮点数。

最佳答案

pyspark中是否有包含整数和浮点数的数据类型,并且可以处理上述两种情况?


那没有。如果您希望代码尽可能通用,则将输出强制转换为可以容纳结果的最通用类型:

 udf(lambda x: float(x[0] + x[1]), DoubleType())


或通过投射输入列来确保始终在调用时使用正确的类型。

 udf(lambda x: x[0] + x[1], DoubleType())
 ...
 udf_add(array('A', 'B').cast("array<double>")


显然,您绝不会在生产代码中使用udf进行简单添加。只需在__add__对象上使用+Column)。仅在不可能提供更有效的解决方案时才使用udf


  如果不是,是否有办法事先确定或不定义数据类型?


不能。返回类型必须事先知道,并且udf是一个黑框-Spark无法确定应该使用什么类型。

关于python - PySPark-在操作后确定dtype的功能,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/49815411/

10-16 01:20