在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/