Python 如何将UDF函数的返回值保存为两列?

Python 如何将UDF函数的返回值保存为两列?,python,python-3.x,apache-spark,pyspark,apache-spark-sql,Python,Python 3.x,Apache Spark,Pyspark,Apache Spark Sql,我的函数get_data返回一个元组:两个整数值 get_data_udf = udf(lambda id: get_data(spark, id), (IntegerType(), IntegerType())) 我需要将它们分成两列val1和val2。我怎么做 dfnew = df \ .withColumn("val", get_data_udf(col("id"))) 我应该将元组保存在一列中,例如val,然后以某种方式将其拆分为两列。或者有更短的方法吗?元组可以像列表一样被

我的函数
get_data
返回一个元组:两个整数值

get_data_udf = udf(lambda id: get_data(spark, id), (IntegerType(), IntegerType()))
我需要将它们分成两列
val1
val2
。我怎么做

dfnew = df \
    .withColumn("val", get_data_udf(col("id")))

我应该将元组保存在一列中,例如
val
,然后以某种方式将其拆分为两列。或者有更短的方法吗?

元组可以像列表一样被索引,因此您可以将第一列的值添加为
get_data()[0]
,第二列的第二个值添加为
get_data()[1]

您还可以执行
v1,v2=get_data()
,通过这种方式将返回的元组值分配给变量
v1
v2


查看此处的问题以进一步澄清。

例如,您有一个如下所示的一列数据框示例

val df = sc.parallelize(Seq(3)).toDF()
df.show()

//下面是一个UDF,它将返回一个元组

def tupleFunction(): (Int,Int) = (1,2)
//我们将从上面的UDF创建两个新列

df.withColumn("newCol",typedLit(tupleFunction.toString.replace("(","").replace(")","")
.split(","))).select((0 to 1)
.map(i => col("newCol").getItem(i).alias(s"newColFromTuple$i")):_*).show

您可以在udf中创建structFields,以便以后访问

from pyspark.sql.types import *

get_data_udf = udf(lambda id: get_data(spark, id), 
      StructType([StructField('first', IntegerType()), StructField('second', IntegerType())]))
dfnew = df \
    .withColumn("val", get_data_udf(col("id"))) \
    .select('*', 'val.`first`'.alias('first'), 'val.`second`'.alias('second'))

如果我使用列(“val1”,get_data_udf(col(“id”)[0])执行
,使用列(“val2”,get_data_udf(col(“id”)[1])
,那么我将调用
get_data_udf
两次。不是吗?另外,如果我在数据帧中按行运行此函数,我如何运行
v1,v2=get_data()
?将第一个放在循环中,并将v1和v2逐行附加到df中-这就是它的工作方式!你能补充一些例子吗?但是循环通常不用于分布式编程。也许我误解了你的想法。因此,该示例将非常有用。@Markus:如果您不想运行两次udf,则需要将结果暂时保存在单独的列中。另请参见scala中的
。withColumn(“val1”,col(“val.\u 1”))。withColumn(“val2”,col(“val.\u 2”)
,不确定这在pysparkIt的scala中是否有效,否?我需要Python,没错。只有薄纱的功能不同。除此之外,实际代码是spark api。它应该可以工作
的含义是什么。选择('*'
?它表示所有列。啊,好的。有必要执行
删除(“val”)
,对吗?不确定。