我使用现有的Dataframe并使用包含元组的字段创建一个新的Dataframe。 UDF用于生成此字段。例如,在这里,我采用源元组并修改其元素以生成新元素:
udf( lambda x: tuple([2*e for e in x], ...)
挑战在于元组的长度是事先不知道的,并且可以在行之间变化。
从我理解阅读相关讨论,返回一个元组,UDF的返回类型必须声明为StructType。但是,由于返回的元组中的元素数量未知,我不能只写出类似的内容:
StructType([
StructField("w1", IntegerType(), False),
StructField("w2", IntegerType(), False),
StructField("w3", IntegerType(), False)])
似乎可以返回列表,但列表对我来说不起作用,因为我需要在输出Dataframe中有一个可散列对象。
我有什么选择?
提前致谢
答案 0 :(得分:2)
StructType
/ Row
表示固定大小的product type对象,不能用于表示可变大小的对象。
要表示同类集合,请使用list
作为外部类型,并使用ArrayType
作为SQL类型:
udf(lambda x: [2*e for e in x], ArrayType(IntegerType()))
或(Spark 2.2或更高版本):
udf(lambda x: [2*e for e in x], "array<integer>")
在Spark 2.4或更高版本中,您可以使用transform
from pyspark.sql.functions import expr
expr("tranform(input_column, x -> 2 * x)")
答案 1 :(得分:0)
每个Databricks(Spark)的新语法一次排成一行(与Pandas UDF一致,这似乎是udfs在python https://databricks.com/blog/2017/10/30/introducing-vectorized-udfs-for-pyspark.html中的作用):
一次一行:
@udf(ArrayType(IntegerType()))
def new_tuple(x):
return [2*e for e in x]